i´m trying to create a map based on LeafletJS. I need some shapes rendered in the map.
I need - for example "Kreis Wesel" (part of germany) in my map. I downloaded shapefiles from http://www.gadm.org/country and imported them into OpenJump. Fine - they are displayed correctly in the GUI.
When i copy the area to clipboard an format id as JSON (with my texteditor) and parse it width 'L.polygon(var).addTo(map', the polygon is created correctly - but in the Indian Ocean, not in Germany.
Any ideas wheres my fault?
Well it seems you can find info in that previous thread
first two lines: " Is there a service that can provide custom tiles in the EPSG:4326 projection? I've looked at Cloudmade and it would be the ideal solution but their tiles are using Spherical Mercator"
The shapes you downloaded are in lat/lon coordinates epsg:4326 whereas your base layer OpenStreetMap uses Spherical mercator epsg:3857
Change your shape's epsg with your favorite GIS software.
Related
I am using deck.gl to render a geojsonlayer using their geojsonlayer function, where the source of data is a geojson file.
Now I want display an infowindow to show area & perimeter of each feature, when clicked on them on the map. I have managed to fetch the properties object of a particular feature and show its reverse geocode address and display them in the infoWindow (pic below),
which also gives me access to the geofence coordinates of that particular feature. But I am not able to find any function from the documentation that allows us to calculate the area. Is there anything I missed here? Or Do I have to calculate it manually based on cartesian space and spheroid?
I found turf.js that does the job for calculating area and perimeter of a geojson feature.
I'm following along Mike Bostock's example for creating a geoJSON projection by downloading and converting shapefiles to geoJSON. I've downloaded the files correctly, and they're online here:
https://bl.ocks.org/KingOfCramers/2c5ceb2e7526a8370d6926958654cf21
This works fine (obviously in the future I'll simplify the shape file to get it to run faster on a browser). Right now, I want to be able to replicate this process quickly for other shapefiles. I've downloaded many from Natural Earth and have converted them successfully into JSON files for use in geoJSON and topoJSON, but I am unsure how to determine which projection to use on them.
Is there a way to quickly examine a .shp file (or after it's been converted JSON) to determine which D3 projection to use, which "translate" values to use, and any other presets for my projection? Or, if I'm going to use geoproject prior to even mapping the file, how I do I find the values to plug in? Here's Mike Bostock's example:
geoproject 'd3.geoConicEqualArea().parallels([34, 40.5]).rotate([120, 0]).fitSize([960, 960], d)' < ca.json > ca-albers.json
How does he know the rotate value? How does he know which parameters to feed into this function?
For an un-finished example, here's my bl.ock of the current earth, but the projection breaks the JSON, because obviously my projection settings are not right:
http://blockbuilder.org/KingOfCramers/16be1bf014683572086511c6a8bd7470
-- or --
https://bl.ocks.org/KingOfCramers/16be1bf014683572086511c6a8bd7470
I can drop this JSON file into mapshaper, which projects it quickly and flawlessly. I want to be able to do this in D3, or at the very least convert the file before mapping it. I'm assuming that information is stored somewhere in the JSON file? Or can be accessed somehow using the JSON projection converter that Mike Bostock recommends, geoproject? Thanks for any help you can provide!
Key Issue
D3 assumes the file to be projected requires projection - that is to say, it assumes the file has not already been projected. This applies if pre-projecting your files from the command lie so that you can display them without a d3 projection. If using projected features, you will not get the results you want - you must unproject your features first.
If using a standard d3 projection such as d3.geoAlbers, data must be unprojected and contain latitude longitude pairs.
Unprojected vs Projected
Unprojected features are those which have latitude and longitude coordinates, they are points located on a three dimensional globe. To display these we need a projection function (most simply: lat = y, long = x, a plate carree projection).
Projected features are those which have Cartesian x,y coordinates. They are the product of some projection function which as a consequence introduces distortion of some or all of: shape, area, distance, or direction.
Signs of Using Projected Data
Upside Down Features
Upside down features are an easy indicator that your features are already projected. Projected geographic data generally features and origin at the bottom left of the features, as one moves north, y values increase. SVG coordinate space is the opposite, as one moves south y values increase.
When displaying your data in mapshaper if you include a shapefiles .prj file, mapshaper will project your data according to this. This will ensure that north is true. When displaying this data with d3, there is no flip on the y axis unless you bake that into the projection function.
Projection File
Secondly, the prj file that comes with every shapefile (or the vast majority) will tell you if features are projected or not. If your prj file lists anything like Albers, Conic, etc, then you have projected data. You need to have your data "projected" using the WGS84 datum or unprojected (also using WGS84). Data using this coordinate space has the EPSG number of 4326, and the prj file should look something like:
GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]
Coordinate Domain
Lastly, if in mapshaper (or any other GIS utility that handles geojson) you were to export the data as geojson, if you see coordinates in excess of [+/-180,+/-90] you are probably dealing with projected data, which often uses a unit of measure like meters.
If you include a file and a projection function I can provide some more specific signs rather than these generalizations.
Easy Solution
If you don't want to modify the projection the data came in, you can use an identity projection:
d3.geoIdentity().reflectY(true).fitSize([w, h], geojson)
This will not modify the input projection, essentially it is only scaling and flipping the input features to match your intended svg/canvas dimensions.
The downside is you can't take features that are already projected as an Albers Equal Area and convert it straight into a Azimuthal Equidistant projection. Also, this approach may make it difficult to overlay locations with geographic coordinates on top of your pre-projected features - for that you will need to re-create the projection the features originally came in.
The upside is the simplicity, it is fine for choropleths or visualizations where nothing geographic is overlain on the projected features.
More Flexible Solution
Unproject your data first, in mapshaper you can do this, assuming you imported the prj files by using the console window and typing:
proj wgs84
Now you can reproject or preproject for d3. Other tools exist for the command line, while programs like QGIS can help convert data quickly too.
The advantage to this is that you can easily re-apply the projection you used on the command line to any points you want to overlay on top, and of course you can modify the projection easily.
What Project Parameters To Choose
If following the 2nd approach or overlaying geographic coordinates on top of features displayed using the 1st approach, the question of what projection parameters to choose becomes relevant again.
The projection parameters chosen are chosen very specifically and often taken straight from standard projections. The .prj file of a shapefile contains everything you need to re-create the projection used in the shapefile. This answer goes into how to emulate a prj file with a d3 projection.
SpatialReference.org is a great reference for finding parameters to different projections. There is a good chance that the California Albers example was based on a standard projection that you can find on this site, probably this one. Of course though, when Mike Bostock used this projection, he applied it to unprojected data.
I have been trying to google this but with no luck.
Has anyone stumbled across some logics/functions to draw a nice area around a city automaticly?
Like the image below:
What you are looking for is Geo Boundary data. They hold the long/lat to create polygons around the desired city/state/area or whatever area you are looking for.
The U.S. Census Bureau Geography has downloadable files that provide this type of data for the U.S. World Countries - GIS Data has other areas world wide.
OSM has polygon data for level 2 administrative units (country -> prefecture -> county) as well, you can get them via either overpass (ttp://overpass-api.de/api/interpreter) or nominatim (https://nominatim.openstreetmap.org/search) interface. I've written a small tool to do so (https://github.com/tibetty/QueryGeoBoundary), you can find more how-to-do details from my source. After you have such data in hand, it will be easy to draw such polygons upon map 'coz most tools have api in place.
I want to create Open street map that contains cluster of no. of points. If I zoom on map then splits points.
Like if I zoom on map
Now click on cluster..shows like this...
So I need Js for open Street Map not for Leaflet.
I'm not totally sure what you're asking here - leaflet is a map viewing library and OpenStreetMap is a tile / data source. They are totally different, independent things. You can display OpenStreetMap tiles very easily in Leaflet. Tiles are the background mapping that is basically pngs tiled together and you can't interact with it.
And you can also display points of interest (things you can interact with on the map, like your markers above) from OpenStreetMap (or anywhere else) very easily in leaflet. This seems to be what you are trying to do.
To do this you will need to:
Download the points of interest in a suitable format (e.g. Geofabrik) has shapefiles for common points of interest for many different countries and smaller regions. This could be a huge answer, as there are many different ways of doing that, but since I'm not sure what you are trying to achieve I will leave it at that.
Convert them to geoJSON format
Display on the map using leaflet - and it looks like you need leaflet marker cluster to aggregate your markers.
I have a map with a simple WMS layer in spherical mercator projection (rendered by a OSM-Mapnik-TileCache server stack, everything is in EPSG:900913 / EPSG:3857).
First: I can't understand why, if Leaflet uses CRS EPSG:3857, whose unit is meters, I still have to provide coordinates, like maxBounds and center, in WGS84 format, which uses degrees. Is it an API inconsistency?
Second: I need to render a GeoJSON feature expressed in WGS84 coordinates (EPSG:4326), but the shape is visibly distorted (see pics below). Should I convert the shape from EPSG:4326 to EPSG:3857? How? If I do so, I would have coordinates expressed in meters, while Leaflet still expects degrees. How could I fix this?
I made a double check with a simple wms layer in OpenLayers and a GeoJSON overlay and it works fine, so I proved that the distortion is not in the data.
Any clue?
Here is the test GeoJSON, hope someone can understand the reason of the issue:
{
"type": "Polygon",
"coordinates": [
[
[14.740017498458682, 40.673078870109705],
[14.740132563378529, 40.673283531348574],
[14.741625561383819, 40.67246759585111],
[14.741671820229074, 40.672308542443076],
[14.74151049646397, 40.672262934612235],
[14.740017498458682, 40.673078870109705]
]
]
}
Example image on Leaflet
Example image on OpenLayers
First: I can't understand why, if Leaflet uses CRS EPSG:3857, whose unit is meters, I still have to provide coordinates, like maxBounds and center, in WGS84 format, which uses degrees. Is it an API inconsistency?
Projections in data are different than display projections. The input to Leaflet is lat/lon in WGS84, the default output is mercator, in EPSG:3857. EPSG:3857 is rarely used for data encodings.
but the shape is visibly distorted (see pics below).
This is what projections are: this is distorted because projections are distortions.
Should I convert the shape from EPSG:4326 to EPSG:3857?
Leaflet is doing this internally already, you don't need to do it manually.
I made a double check with a simple wms layer in OpenLayers and a GeoJSON overlay and it works fine, so I proved that the distortion is not in the data.
Your OpenLayers map has EPSG:4326 as its display projection, while your Leaflet map has EPSG:3857: this is why one is a different shape.