This is absolutely doing my head in...
I am trying to load buffers that are generated in QGIS 3.4 from OpenStreetMap data (via Overpass) onto a map powered by Leaflet.
When I load them into my map, the buffers that should be perfect circles show up like this:
What I have tried
I have read up on the projections that Mapbox, Leaflet and Geojson support (seems that it's either EPSG: 4326 or EPSG:4326).
As a result, I have saved my original point files from OpenStreetMap as both projections and generated buffers in QGIS from both projections. Both come up with the same result as above, even with changing the project CRS between the two.
The weirdest thing is that the points are in exactly the spot they should be and show up as perfect circles in QGIS.
First few lines of the Geojson file:
var fivekmbuffersupermarkets = {
"type": "FeatureCollection",
"name": "5kmbuffersupermarkets4326",
"crs": {
"type": "name",
"properties": {
"name": "urn:ogc:def:crs:OGC:1.3:CRS84"
}
},
Geojson file code here: https://jsfiddle.net/65fzujk3/
Was contacted by someone else who got this working for me. Never worked out exactly what I was doing wrong but these steps worked for me with the Geojson file linked above:
Add layer
Vector > Data Management Tools > Reproject Layer > 28355
Vector > Geoprocessing Tools > Buffer > 5000m, 8 segments
Vector > Geoprocessing Tools > Dissolve
Vector > Data Management Tools > Reproject Layer > 4326
Never touched the Project CRS at all.
Related
I'm facing a precision issue with Mapbox GL JS when placing an image overlay on the map with 4 corners coordinates, there is a shift from the expected position by 50-250 m. To reach this conclusion and find this bug, the projection of the image was compared to Leaflet and QGIS, both of them shows the same position of the image but Mapbox GL JS is showing a shift.
I think this may be a bug in the framework that needs to be fixed. I'm using React Mapbox GL JS and was able to recreate this issue using Mapbox GL JS library within a normal html file. So most probably it's not being caused by React.
To recreate the issue try to overlay an image on the map using Mapbox, Leaflet and QGIS and then compare the results.
mapbox-gl-js version: 1.4.0
browser: Google Chrome Version 79.0.3945.88 (Official Build) (64-bit)
Steps to Trigger Behavior
Add an image overlay to Mapbox GL JS using 4 coordinates
map.addSource("imageTest", {
"type": "image",
"url": "/DIR/TO/IMAGE",
"coordinates": [
[LON1,LAT1],
[LON2,LAT2],
[LON3,LAT3],
[LON4,LAT4]
]
})
map.addLayer({
"id": "overlay",
"source": "imageTest",
"type": "raster"
})
Geo reference the same image using GDAL Georeferencer on QGIS with the same coordinates and use QGIS to load the resulting GeoTIFF.
Overlay the image using Leaflet Distortable Image https://github.com/publiclab/Leaflet.DistortableImage
Compare the 3 projections, a shift shall be observed only with the Mapbox projection and on the y axis most probably.
Expected Behavior
All of these methods should yield the same results.
Actual Behavior
Mapbox is showing a major shift sometimes up to 250 meters for an image with a swath of 3 km.
Check this screenshot: (QGIS left, Mapbox center, Leaflet right)
The problem does have to do with projection. Images can be sliced and diced exactly by coordinates but they must match the projection of the map they are being overlaid on. In the case of Mapbox, it uses web mercator and images must be reprojected to EPSG:3857.
A utility to convert images (such as geoTIF) to this projection is GDAL (https://gdal.org/). A command using GDAL tools to convert an image would be something like :
gdalwarp -t_srs EPSG:3857 input.tif input-projected.tif
Hopefully this clears things up.
I'm trying to generate pbf vector tiles from json data using tippecanoe. Ultimately will be served up for use in OpenLayers but had no success there so tried testing the tiles in QGIS. When I view any of them (in QGIS) instead of being in the longitude range of -180 to +180 they are in the ~2000 to ~4000 range.
I have a simple json file consisting of a rectangle surrounding Europe using EPSG:4326.
I use tippecanoe to generate the pbf tiles.
jim.json consists of:
{"features":[{"geometry":{"coordinates":[[0,0],[0,80],[80,80],[80,0],[0,0]],"type":"LineString"},"properties":{"level-index":1,"level-value":956.0,"stroke":"#a52a2a","stroke-width":1,"title":"956.00 "},"type":"Feature"}],"type":"FeatureCollection","crs":{"type": "name","properties": {"name": "urn:ogc:def:crs:OGC:1.3:CRS84"}}}
Then I run this command:
tippecanoe --no-feature-limit --no-tile-size-limit --no-tile-compression -s EPSG:4326 --output-to-directory TilesDir --force jim.json
Then if I try to see if the tiles are correct, I take the largest one (0/0/0.pbf) into QGIS and the rectangle gets plotted outside of the earth out at 2000degE instead of in the expected area near Europe.
It turns out that QGIS is not the appropriate tool to test the pbf. After correcting some other issues, I was able to display the pbf in OpenLayers. I assume tippecanoe generates the pbf with some internal coordinate system (4096x4096 pixels?) not the EPSG:4326 that I was expecting.
My map's source file is GeoJSON, but it is very large and very slow. Is there a way to convert this to vector tiles on the fly using MapBox GL JS? (Load the GeoJSON, pre-process the file into vector tiles, and show use the vector tiles as the base map.) It seems that vector tiles are much faster.
I've tried all the GeoJSON-VT tutorials and examples that I could, like the one on MapBox's site, but it just says that GeoJSON-VT works under the hood, so it isn't much help. The others mostly apply to Leaflet, not MapBox GL JS.
Meanwhile, every example I find that uses a large dataset always does so via vector tiles:
map.addSource('x', {
"type": "vector",
"url": "url"
});
For reference, I am loading my file using this method:
map.addSource('x', {
type: 'geojson',
data: 'file.geojson'
});
In case your GeoJSON file is static, you could use mapbox/tippecanoe to convert the GeoJSON to an .mbtiles file. You could then either upload the file to Mapbox as a tileset (about tilesets) or you could serve your own vector tile source from a web server using the .mbtiles file (reference implementation).
If your GeoJSON file is more dynamic, things get a little bit more complicated. I have never used it, but Mapbox Dataset API might be a good solution for that.
To the best of my knowledge, Mapbox-GL-JS uses GeoJSON-VT to automatically convert client-side-loaded GeoJSON files into vector tiles within the browser - so it's already doing what you're asking for.
If this is still "slow", probably the problem is the actual loading and processing - so pre-generating and serving vector tiles is the right answer.
Learning Leaflet. Had success with point data. Now want to create polygons.
The process starts with an Access record with a Parcel Identification Number. Using ArcMap desktop, the records are joined to a parcel shape file for the county.
What the best approach to get to Leaflet polygons from here? Like with point data, do I need to add fields to contain the lat/lon data?
I don't need a lot of detail; just a pointer in the right direction. I don't mind doing homework.
My approach would be to convert the shapefile to geojson and then load the geojson into your Leaflet map.
I'm aware of some ArcGIS plugins to export geojson, but an alternative approach is to use the command line tool GDAL (ogr2ogr).
See the links on this answer for more details, but the command will end up being something like the following...
ogr2ogr -f GeoJSON -t_srs "EPSG:4326" [name][.geojson|.json] [name].shp
From there you can preview the results in geojson.io or github before creating your Leaflet map.
I'm working on a project using Leaflet. For this project I've created an interface to draw all the roofs of a large city as polygons. A lot of scripts calculate the surfaces, the addresses, the orientation and so on... I'll store each roof's datas in a geojson file (or files). We expect to get about 10 000 roofs or more. I don't know if Leaflet displays only visibles polygons depending window's boundaries or if all the polygons are drawn, and my problem is to find the better way to do this storage.
In one geojson file. It may be a problem because the 10 000 roofs are computed in the same time and waiting for polygons loading may be very boring for users.
In separated geojson files: for each roof I can approximatively calculate the coordinates of its center and put this roof in the right geojson file depending the lat/lng. By this way I can create (say 20 or 50) differents geojson files and call the right one depending boundaries. Then the question is: to create all the polygons, is it better to call the 6 (or 8 or 10) geojson usefull files for the area on screen, or is it better to create a new dynamic geojson file?
All the roof's datas are stored in a database or in a XML file and I have to detect boundaries and automatically create a dynamic geojson file. But each time user scroll or darg or zoom the map I'm supposed to recreate this unique geojson file...
Do you ever have a similar problem to solve and how do you solve it ? Thx.
I think the second scenario is the most robust, you need tiled GeoJSON tiles. Have a look at Leaflet Plugins. There is one called TileLayer.GeoJSON. Some links on how to create these tiles are on OpenStreetMap wiki.