Trying to Render buildings shapefiles

Hi,

I might sound very naive, but kindly bare with me I am very new to cesium.

I have some shapefiles having polygons(buildings) with height as one of its attributes. I was able to successfully extrude it by converting it to Geojson and passing it to GeoJsonDataSource.

But for some shapefiles the polygons are rendered all over the globe (see attachment). I think the problem is with the projection system of the shapefile. Using qgis I was able to change its CRS to WGS84 and then it worked fine. But I want to change the CRS on the web itself rather than changing it using some GIS tool. Is there a way I can convert I can do this in cesium?

If its not possible I was thinking of using proj4js library to do the conversion, but I don’t know how can I get the geometry/coordinates of the polygons from the entity.polygon object?

This is the code that i am using for extrusion.

dataSource.load(geojson).then(function() {
var entities = dataSource.entities.values;

            for (var i = 0; i < entities.length; i++) {
                var entity = entities[i];
                var color = Color.White;

                entity.polygon.material = color;
                entity.polygon.fill=true;
                entity.polygon.outlineColor = Color.BLACK;

                //Attribute for the height:
                entity.polygon.extrudedHeight = 3.5*entity.properties.HT_RANDOM;
            }  
        });

Hello, I fear Cesium can natively only use 2 CRS : "EPSG:4326" (http://cesiumjs.org/Cesium/Build/Documentation/GeographicProjection.html) and "EPSG:3857" (http://cesiumjs.org/Cesium/Build/Documentation/WebMercatorProjection.html). It seems you could create your own projection by implementing MapProjection (http://cesiumjs.org/Cesium/Build/Documentation/MapProjection.html).

In order to have the coordinates of your polygon, you'll need to work with the attribut hierarchy of PolygonGraphics (http://cesiumjs.org/Cesium/Build/Documentation/PolygonGraphics.html). This attribut is a property, also, to retrieve the data, you must use a JulianDate.

For example:
var hierarchyProperty=entity.polygon.hierarchy;
var time=Cesium.JulianDate.now();
var hierarchy=hierarchyProperty.getValue(time);

now hierarchy contains a PolygonHierarchy instance (http://cesiumjs.org/Cesium/Build/Documentation/PolygonHierarchy.html) with your coordinates:
the position array is hierarchy.positions . The positions are defined in cartesian 3d, maybe you'll need to convert to cartographic...

bobactor is partially right, GeoJSON handles CRS “urn:ogc:def:crs:OGC:1.3:CRS84” and “EPSG:4326” by default. If the CRS is the problem, you can easily add a new one, but there’s no need to create a MapProjection, you just specify a function that can convert from the files projection to earth-fixed.

The code looks like this:

GeoJsonDataSource.crsNames[‘projectionName’] = function(coordinates){

//convert coordinates array to Cartesian3

};

For a concrete example, if we didn’t handle 4326 automatically, you would add it with the following code

GeoJsonDataSource.crsNames[‘EPSG:4326’] = function(coordinates){

return Cartesian3.fromDegrees(coordinates[0], coordinates[1], coordinates[2]);

};

The conversion is done one point at a time, you never get the entire array at once. If you hook up code to use proj4js to handle projections in GeoJSON, I would love to hear about it.

Hi,

Does your GeoJSON load correctly in National Map? Just drag/drop it in and see if it works. If it does, I can point you to the code we use. If not, I’ll be interested in learning why.

Kevin

something else to add to the mix, this is another project the primary developer for proj4js has:

https://github.com/calvinmetcalf/shapefile-js

also

some other projects for creating shapefiles in the browser

https://code.google.com/p/js2shapefile/

https://github.com/mapbox/shp-write

Thanks for the links. One of our project ideas for Google Summer of Code this year is native support for Shapefiles in Cesium, so thanks for the links.

Hi all,

Turns out the projection system of the file is WGS 84 and converting it to “EPSG:32245” (UTM 45N) gives reasonable results. I converted it to geojson and here is how they look in National Map(see attachments), and I have been using this library to convert the shapefiles to geojson object:
https://github.com/calvinmetcalf/shapefile-js

After using bobactor code, I can get the cartesian3d, but I don’t know how can I convert it to the initial cartographic lat/log values for the geometries, which I might pass to the proj4js function?

As suggested by Marrhew, I defined a function GeoJsonDataSource.crsNames[‘EPSG:32245’], which takes the coordinates and converts it to the target projection system, using proj4js. Then I use this method to convert each coordinate of the geojson object. But unfortunately, the results are not as expected, it is giving 0 value for every y value when I try to use UTM 45N projection system(EPSG:32245). I think I am missing something in the proj4js library ?

In the code below the firstProjection and the secondProjection are the strings that I have taken from the .prj files of the shapefiles. My guess is the projection system that i am trying to convert to might not be defined in proj4js?

Code:
GeoJsonDataSource.crsNames[‘EPSG:32245’] = function(coordinates){

        var firstProjection = 'GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]';
        var secondProjection = 'PROJCS["WGS_72_UTM_zone_45N",GEOGCS["GCS_WGS 72",DATUM["D_WGS_1972",SPHEROID["WGS_1972",6378135,298.26]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",87],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["Meter",1]]';
     
        var xa = coordinates[0];
        var ya = coordinates[1];
        console.log('Initial Coordinates ' + coordinates);

        var newCoordinates = proj4(firstProjection,secondProjection,[xa,ya]);
        console.log('New Coordinates' , newCoordinates);

    };

Here are some of the conversion:

“Initial Coordinates 581980.5863617394,1880350.8478933717”
“New Coordinates” Array [ -1096369.785743386, 0 ]

“Initial Coordinates 581973.1002422537,1880348.8447118145”
“New Coordinates” Array [ -1096347.8667143777, 0 ]

“Initial Coordinates 581970.4246029982,1880358.8357755134”
“New Coordinates” Array [ -1096329.4536635897, 0 ]

from the proj4 js page

proj4(fromProjection[, toProjection2, coordinates])

your source shapefile is the “from” projection,EPSG:32245 you will want to go to EPSG:4326 for catographics

http://epsg.io/32245 has the proj4 string definition for "WGS 72 / UTM zone 45N " a little easier to work with here vs the WKT definition

should be able just go

var EPSG_32245 = ‘+proj=utm +zone=45 +ellps=WGS72 +towgs84=0,0,4.5,0,0,0.554,0.2263 +units=m +no_defs’;

var cartos = proj4(EPSG_32245,proj4(‘EPSG:4326’),[581973.10,1880348.84]);

this should generate a long lat pair in degrees

Thanks Berwyn that worked. :slight_smile: