I've read through every question on Stack Overflow I can find and every example I can find on the web for adding GeoJSON vector tiles to a leaflet map. Unfortunately I still can't manage to wrap my head around it, much less get it work on my data.
I have a GeoJSON (here) with many points. I can add it just fine as a layer in Leaflet, so I feel confident that it's a valid file with real values.
I've tried geojson-vt and leaflet vector grid.
geojson-vt keeps returning an error:
Uncaught ReferenceError: z is not defined at <anonymous>:1:30
with this code:
geoJson = {data}
var tileOptions = {
maxZoom: 18,
tolerance: 5,
extent: 4096,
buffer: 64,
debug: 0,
indexMaxZoom: 0,
indexMaxPoints: 100000,
};
var tileIndex = geojsonvt(geoJson, tileOptions);
var tile = tileIndex.getTile(z, x, y);
I'm having a lot of trouble diagnosing this because none of the examples I've found have shown their data, but also none have referenced defining z, x, and y, and those aren't required values for a GeoJSON object. What am I missing?
From another question of mine I learned that Leaflet vector grid has an error with GeoJSON points. I managed to change some of the source code to resolve the initial error, but now get over 1,000 errors like:
Error: <path> attribute d: Expected number, "MNaN,47.5aundefin…".
from the code:
L.vectorGrid.slicer(geoJson).addTo(map)
How can I add GeoJSON points as a vector tile layer to a leaflet map? Does anyone have any simple examples with data as a reference? Any help or other directions to investigate would be appreciated.
I've had a look at this for a few minutes, and I've concluded there are bugs in Leaflet.VectorGrid affecting slicing points. I've opened a bug report with relevant information.
I was able to resolve the issue I was experiencing with Leaflet.VectorGrid.Slicer.
First I downloaded the Leaflet.VectorGrid.js source code and changed the lines indicated here (note that that corresponds to lines 1483 to 1495 from the source code available on the VectorGrid github site).
Then, after troubleshooting, I found that if I added a radius option when calling L.vectorGrid.slicer, the GeoJSON points were added to the map. This is the code that worked:
var layer = L.vectorGrid.slicer(geoJson, {
vectorTileLayerStyles: {
sliced: {
radius: 1,
}
}
}).addTo(map);
Related
So ive got a 2000x2000 image as a CRS map where i need to fit -600000 +600000 coordinates, but the image becomes so zoomed that im obviously not doing it right, i guess the program does not know how to combine and calculate that by itself to fit the units into pixels, or does it have a setting for that?
I guess it still makes each pixel of the image approx 600units big but i guess thats accurate enough for what im trying to do.
Coordinates themselves seem to be working as the center of the image is exactly spot on.
var mapOptions = {
center: [11999, 9199],
minZoom: 0,
maxZoom: 0
}
// Creating a map object
var map = L.map('bigmapleaf', {
crs: L.CRS.Simple
}, mapOptions);
var bounds = [[600000,-600000], [-600000,600000]];
var image = L.imageOverlay('../pictures/map.png', bounds).addTo(map);
// Adding layer to the map
map.fitBounds(bounds);
map.setView( center, 1);
Edit:
Now i have managed to find the math that makes the map the right size without any zooming with good precision, but i need to make the map to respond to those kind of large units which i believe requires another conversion back to the original units which does not feel right. I wish i could work with the large units and let leaflet do all the map view conversions. Maybe i try to make a script that discusses both ways with their own units.
Still waiting if someone knows easy answer for my troubles.
In addition to being easier working with them large units, i could also make the map with absolute accuracy.
I'm pretty new in using OpenStreetMaps with leaflet and got stuck trying to find out if there is a smarter way to include a boundary that I found on a map with markers that I created.
The best way I found until now is to find the area I need to show behind my markers ( for example this area : https://www.openstreetmap.org/relation/3123501#map=9/54.1375/-1.3898 ) and convert that to a list of lat/long coordinates that I add using (shortened the poly coordinates) code like this:
var latlngs = [
[54.1508316, -2.5609075],
[54.1498313, -2.5577575],
];
var polygon = L.polygon(latlngs, {color: 'rgba(0, 128, 0, 1.00)'}).addTo(map);
// zoom the map to the polygon
map.fitBounds(polygon.getBounds());
It produces the output I want but having 10k coordinates does not seem like an effective way to do this. Unfortunately my google and reading afforts dit not help me (yet) so I'm asking if somebody can point me in the right direction (if there is any) to do this in a smarter way.
Thanks in advance.
I'm just getting started with MapBox, and I successfully created a style using MapBox Studio. This style has a layer full of points from a dataset I uploaded.
I would like to create an effect through which some of these points are in constant movement. I know I can move all points by applying a setPaintProperty to the circle-translate property. But what about individual ones?
In other words, how should I go about moving individual points I added to my map in MapBox Studio from JavaScript?
The normal way to move some points would be to use .setData() to update the entire dataset.
See this example for that approach: https://www.mapbox.com/mapbox-gl-js/example/rotating-controllable-marker/
Your alternative method, using circle-translate sounds like it would work for moving some points, if it supported data-driven styling, which it doesn't.
However, if you are ok with having a layer in which all the points move in the same way, then this should work:
let offset = [0, 0];
map.addLayer({
id: 'somepoints',
type: 'circle',
paint: {
'circle-translate': offset
},
filter: [...insert filter here...]
});
Whenever you need the points to move:
offset = [3, -2]; // or whatever
map.setPaintProperty('somepoints','circle-translate', offset);
I am using Australian government map data found here: Victoria, Australia locality data, which is provided in the EPSG4326 projection.
When I try to use the data with leaflet, of course, my data is a bit distorted due to the earth's curvature - so my data is not represented properly on the screen because the maps are using a different projection to my data.
I have tried to force the map to use EPSG4326 by setting it in Map options and also in the TileLayer, as shown here:
var gisLayer = L.tileLayer(
'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
//subdomains: ['0', '1', '2', '3'],
attribution: 'openstreetmap',
reuseTiles: true,
updateWhenIdle: false,
crs: L.CRS.EPSG4326
});
var map = L.map('map', {
center: [-28.5, 135.575],
zoom: 4
,crs: L.CRS.EPSG4326
});
map.addLayer(gisLayer);
but when I do this, the maps do not display. I don't believe the map tiles have been generated for this projection. That said, there is a suggestion in the docos here that it might be possible, but I couldn't get this working. (Did I just get the configuration wrong?)
It seemed like it was working when I retrieved the data and placed it on the map, but when I got the map bounds to select the data for the visible region, it also showed distorted. So I tried to convert the map bounds to EPSG4326 manually, to pass that to the database, as follows:
var bounds = map.getBounds();
var coords4326_NE = L.Projection.SphericalMercator.unproject(bounds._northEast);
console.log(coords4326_NE);
but that broke the code. I was passing the wrong structure in and I couldn't get this right either.
Of course, I would also accept transforming every point returned from the database to the default projection, which I think is EPSG3857. But I am having doing this as well.
I have provided as jsFiddle here where I have been attempting to do the above.
Does anyone know how I can achieve this?
Your GeoJSON data is encoded in WGS84, which can be simply plotted on EPSG4326, but is also the expected input for EPSG3857 (Web Mercator).
From that Wikipedia article:
While the Web Mercator's formulas are for the spherical form of the Mercator, geographical coordinates are required to be in the WGS 84 ellipsoidal datum.
Therefore, you do not have to change anything to plot your data onto a regular Leaflet map, using regular tiles (from OSM or Mapbox, which provide tiles only for EPSG3857).
I'm using leaflet.draw, and when a rectangle is created, i'm fetching rectangle's data using layer.toGeoJSON(), and then i save it into a db using ajax.
After that, when the user display the map again, i'm loading previously saved data, and push them into the featureGroup reserved for leaflet.draw using L.GeoJSON.geometryToLayer()
Problem is that my previously created rectangle is now a real polygon for leaflet.draw.
"Rectangle" does not exist in geoJson specs, so i can understand that.
Now, in "properties" of the geojson, i know that the previous shape was a rectangle, with the "type" attribut.
My question is : is there a way to force a shape to be a rectangle in a leaflet.draw point of view ?
Thanks in advance !
I ran into this same problem and have come up with a solutions which works for me although it isn't the most elegant method.
Using leaflet.draw I receive a new layer on which I call layer.toGeoJSON() to save the rectangle to my database. On refresh of the page I'm pulling that GeoJSON representation back from my database and storing it with:
var geojson = JSON.parse(geojson_string);
What I tried first was to build my own Rectangle from the points and add it to drawnItems.
var bounds = L.latLngBounds(geojson.geometry.coordinates);
var rect = L.rectangle(bounds);
drawnItems.addLayer(rect);
This code did not throw an error, but it also didn't show a rectangle on the map. After further investigation I found the coordinate pairs output from layer.toGeoJSON() and the coordinate pairs needed by L.latLngBounds() were reversed (i.e. one was [lat, lng] and the other was [lng, lat]) which caused the Rectangle to be created but in entirely the wrong location. To get around this I constructed the layer first as a GeoJSON layer which results in a polygon, but then use that representation's bounds to construct my Rectangle.
var geojson_layer = L.GeoJSON.geometryToLayer(geojson);
var rect = L.rectangle(geojson_layer.getBounds());
drawnItems.addLayer(rect);
This successfully creates a Rectangle which leaflet.draw recognizes and allows for the edit tools to work correctly.