I'm trying to use the leaflet API to display data about Coral Reef locations across the world. I originally downloaded a shapefile (.shp), and converted it to GeoJSON using QGIS. I put the data in my project folder, but when I attempted to display this data on leaflet through an Ajax request, the browser took a very long time to load and eventually return a not responding message. However, I could see that the markers would appearing on the map, albeit it very slowly. Is there any way to create a smaller file, or load the data more efficiently so it doesn't make the entire site unusable?
My Ajax request looked like this:
$.ajax({
type: 'GET',
url: './coldwater.geojson',
dataType: 'json',
data: data,
success: function (data) {
L.geoJSON(data).addTo(mymap);
}, error: function(){
console.log('Couldn\'t load data');
}
});
Here's a snippet of the geoJSON
{
"type": "FeatureCollection",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
"features": [
{ "type": "Feature", "properties": { }, "geometry": { "type": "MultiPoint", "coordinates": [ [ -75.116700000304718, 18.283300000094982 ], [ -75.116699858211859, 18.283301156623111 ] ] } },
{ "type": "Feature", "properties": { }, "geometry": { "type": "MultiPoint", "coordinates": [ [ -34.850000000399632, 9.01670000040474 ], [ -34.849996660317572, 9.016695959750791 ] ] } },
{ "type": "Feature", "properties": { }, "geometry": { "type": "MultiPoint", "coordinates": [ [ -34.850000000399632, 9.01670000040474 ], [ -34.849996660317572, 9.016695959750791 ] ] } },
{ "type": "Feature", "properties": { }, "geometry": { "type": "MultiPoint", "coordinates": [ [ -81.166699999905006, 23.983300000394763 ], [ -81.166699953140267, 23.983303104854429 ] ] } },
{ "type": "Feature", "properties": { }, "geometry": { "type": "MultiPoint", "coordinates": [ [ -79.549997733808311, 26.649999766076405 ], [ -79.416700222836994, 27.166696245435446 ], [ -79.416700222836994, 27.283302340130945 ], [ -79.416699999805132, 27.283300000094982 ] ] } },
{ "type": "Feature", "properties": { }, "geometry": { "type": "MultiPoint", "coordinates": [ [ -78.683303107752181, 27.416698775628049 ] ] } },
{ "type": "Feature", "properties": { }, "geometry": { "type": "MultiPoint", "coordinates": [ [ -79.216699996607531, 24.099999131754601 ], [ -78.850001440414133, 26.516702255105031 ], [ -78.39999868309269, 26.583297050818317 ] ] } },
{ "type": "Feature", "properties": { }, "geometry": { "type": "MultiPoint", "coordinates": [ [ -77.083301298815854, 25.166702977260627 ] ] } },
{ "type": "Feature", "properties": { }, "geometry": { "type": "MultiPoint", "coordinates": [ [ -79.233301481578053, 27.216698550297906 ], [ -79.216699996607531, 27.300002749627254 ] ] } },
{ "type": "Feature", "properties": { }, "geometry": { "type": "MultiPoint", "coordinates": [ [ -79.549997733808311, 26.649999766076405 ], [ -79.416700222836994, 27.166696245435446 ], [ -79.416699999805132, 27.166700000104981 ], [ -79.366697917974477, 27.533295877103114 ] ] } },
Would it be better to use the google maps API?
Or is there a better way to insert a shapefile into a leaflet map?
ps: if this isn't appropriate or is off topic let me know. I'm new to posting on stackoverflow
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I want to create a data object dynamically with key-value pairs. In this object, there is also an array named features and also within this array element called geometry one more array coordinates.
In feature array, properties like title and content will add dynamically and also values of coordinates array.
How to add data in coordinates array: "geometery":{"coordinates":[]}.. ?
data = {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"properties": {
"title": "Day 1",
"content": "This is where some people moved to."
},
"geometry": {
"type": "Point",
"coordinates": [
-73.7949,
40.7282,
1
]
}
},
{
"type": "Feature",
"properties": {
"title": "The Next Day",
"content": "This is where some people grooved to."
},
"geometry": {
"type": "Point",
"coordinates": [
-74.3838,
40.9148,
1
]
}
},
{
"type": "Feature",
"properties": {
"title": "Amazing Event",
"content": "This is where they went to have fun."
},
"geometry": {
"type": "Point",
"coordinates": [
4.899431,
52.379189,
1
]
}
},
{
"type": "Feature",
"properties": {
"title": "1776",
"content": "This where they went when the revolution had begun."
},
"geometry": {
"type": "Point",
"coordinates": [
-71.3489484,
42.4603719,
1
]
}
},
{
"type": "Feature",
"properties": {
"title": "1776",
"content": "This where they went when the revolution had begun."
},
"geometry": {
"type": "Point",
"coordinates": [
-71.2272,
42.4473,
1
]
}
},
{
"type": "Feature",
"properties": {
"title": "1984",
"content": "So they all came here...and disappeared without a trace!"
},
"geometry": {
"type": "Point",
"coordinates": [
-0.118092,
51.509865,
1
]
}
},
{
"type": "Feature",
"properties": {
"title": "12/22/63",
"content": "Now, this can be quite the scary place."
},
"geometry": {
"type": "Point",
"coordinates": [
-70.2553259,
43.661471,
1
]
}
},
]
}
var data = {
features: []
};
for (piece in pieces){
data.features.push({
type: "Feature",
properties: {title: '{piece.title}' , content: '{piece.content}' },
geometry: {type: "Point"},
});
}
What have you already tried and where was your problem?
You could do something like this:
var data = {
features: []
};
data.features.push({
type: "Feature"
});
I'm trying to render multiple points using Mapbox but it only displays the last one. I've added the feature parameter but nothing. This should render the two markers but i don't know why it doesn't. I'm not getting any errors in the console.
I'm stuck and can't find a way to solve it. Help?
This is the code responsible for the points.:
map.on('load', function() {
map.loadImage('images/celltower.png', function(error, image) {
if (error) throw error;
map.addImage('tower', image);
map.addLayer({
"id": "points",
"type": "symbol",
"source": {
"type": "geojson",
"data": {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [21.42559803007430, 42.00038270989050]
},
"geometry": {
"type": "Point",
"coordinates": [21.38529272846381, 42.0080397578202]
}
}]
}
},
"layout": {
"icon-image": "tower",
"icon-size": 0.25
}
});
});
});
Thanks :)
You have a duplicate geometry key. Judging by the fact that features is an array, I would guess this is the proper way to do it:
map.on('load', function() {
map.loadImage('images/celltower.png', function(error, image) {
if (error) throw error;
map.addImage('tower', image);
map.addLayer({
"id": "points",
"type": "symbol",
"source": {
"type": "geojson",
"data": {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [21.42559803007430, 42.00038270989050]
}
}, {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [21.38529272846381, 42.0080397578202]
}
}]
}
},
"layout": {
"icon-image": "tower",
"icon-size": 0.25
}
});
});
});
According to the GeoJSON specification, there should be a way to specify multiple points. E.g.:
"features": [{
"type": "Feature",
"geometry": {
"type": "MultiPoint",
"coordinates": [
[21.42559803007430, 42.00038270989050],
[21.38529272846381, 42.0080397578202]
]
}
}]
I'm trying to simulate city traffic movements (at the moment I'm only into vehicles) but I'm having a problem.
What happens is that I'm trying to simulate 1 car per point at the map, but I don't know how to duplicate a certain layer (and each one has a different route), for example this one:
map.addSource('point', {
"type": "geojson",
"data": pointOnCircle(0)
});
map.addLayer({
"id": "point",
"source": "point",
"type": "circle",
"paint": {
"circle-radius": 10,
"circle-color": "#007cbf"
}
});
I don't know if I could just loop and generate N points with different names or do it in another way.
Here's a video of what I've done until now (for simulating it I created 2 different layers because I didn't know how to duplicate them) :
https://www.youtube.com/watch?v=xWZD9aBUFlg
You should put all your points in the one data layer:
map.addSource('points', {
"type": "geojson",
"data": pointsOnCircle(0) // change this function to return multiple features
});
map.addLayer({
"id": "points",
"source": "points",
"type": "circle",
"paint": {
"circle-radius": 10,
"circle-color": "#007cbf" // possibly make this a data-driven function
}
});
Your GeoJSON data source would look like:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Point",
"coordinates": [
146.25,
-37.16031654673676
]
}
},
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Point",
"coordinates": [
138.515625,
35.460669951495305
]
}
},
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Point",
"coordinates": [
-81.5625,
33.43144133557529
]
}
}
]
}
I'm trying to change geojson marker icon on click following various exemple found on the web but I can't get it to work, it raise this error message:
TypeError: e.target.setIcon is not a function
Bellow the snippet
var map = L.map('map',{ center: [44.1, 3.5], zoom: 10});
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', { attribution: 'OpenStreetMap'}).addTo(map);
var icon = L.icon({
iconUrl: 'https://cdn1.iconfinder.com/data/icons/Map-Markers-Icons-Demo-PNG/256/Map-Marker-Marker-Outside-Azure.png',
iconSize: [ 48, 48 ],
});
var data = {
"type": "FeatureCollection",
"name": "test",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
"features": [
{ "type": "Feature", "properties": { "NUM": 1 }, "geometry": { "type": "MultiPoint", "coordinates": [ [ 3.75, 44.25 ] ] } },
{ "type": "Feature", "properties": { "NUM": 2 }, "geometry": { "type": "MultiPoint", "coordinates": [ [ 3.25, 44.0 ] ] } }
]}
L.geoJson(data,{
pointToLayer: function (feature, latlng) {
return L.marker(latlng);//, {icon: icon});
},
onEachFeature: function (feature, layer) {
layer.on('click', function (e){
e.target.setIcon(icon);
})
}
}).addTo(map);
what's wrong?
The issue is originating from the GeoJSON. It does seem to be a valid GeoJSON because it plots on the map, but it must be tripping up Leaflet somehow. I think the fact that it's a MultiPoint feature is the cause.
Changing the GeoJSON to:
var data = {
"type": "FeatureCollection",
"name": "test",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
"features": [
{ "type": "Feature", "properties": { "NUM": 1 }, "geometry": { "type": "Point", "coordinates": [ 3.75, 44.25 ] } },
{ "type": "Feature", "properties": { "NUM": 2 }, "geometry": { "type": "Point", "coordinates": [ 3.25, 44.0 ] } }
]}
makes it work. (Note: I just changed "type" from MultiPoint to Point and removed the double brackets, i.e. [ [ 3.25, 44.0 ] ] became[ 3.25, 44.0 ].)
I'm not sure if it's possible to use MultiPoint geometry with the onEachFeature function, but it seems to be working with single point geometry.
I have a list of features and I want to create a FeatureCollection to group them in one string, the features are from different types (polygons, lines and points).
Here is how they are written :
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "LineString",
"coordinates": [
[
-31.640625,
15.623036831528264
],
[
-2.8125,
-14.264383087562637
],
[
-22.5,
-30.751277776257812
],
[
-30.937499999999996,
-38.54816542304657
]
]
}
}
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-24.960937499999996,
29.84064389983441
],
[
-2.109375,
21.616579336740603
],
[
2.4609375,
43.068887774169625
],
[
-31.289062500000004,
49.38237278700955
],
[
-24.960937499999996,
29.84064389983441
]
]
]
}
}
Is there a javascript function that deals with this, i'm stuck on it.
If you have an array of GeoJSON feature strings, you can create a GeoJSON feature collection string like this:
var features = [
'{ "type": "Feature", "properties": {}, ... }',
'{ "type": "Feature", "properties": {}, ... }'
];
var collection = JSON.stringify({
features: features.map(JSON.parse),
type: 'FeatureCollection'
});