I am totally stuck with my WGS 84 / EPSG:3857 coordinates and display them on Leaflet.
I have Geojson with coordinates.
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
"6690861",
"682187"
]
},
"properties": {
"id": "908",
"message": "105",
"date": "",
"place": "",
"shape": ""
}
}
Now i want it display on Leaflet. But nothing show up. I search already 5 hours and find something about Proj4. Also no errors showing up.
My script code:
var map = L.map('map').setView([52.2129919, 5.2793703], 8);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {attribution: 'Map data © OpenStreetMap'}).addTo(map);
// GeoJSON layer (UTM15)
proj4.defs('EPSG:3857');
async function addGeoJson() {
const response = await fetch("geojs.php");
const data = await response.json();
L.geoJson(data).addTo(map);
var layerGroup = L.geoJSON(data, {
onEachFeature: function (feature, layer) {
layer.bindPopup('<h1>'+feature.properties.message+'</h1><p>Datum: '+feature.properties.date+'</p>');
}
}).addTo(map);
}
addGeoJson();
It's for my the first time i work with this coordinates. With lat/long coordinates was don't have problems. And just started with javascript.
Kind regards,
I might be a bit late, but following the documentation of Proj4, I would say that you need to add the crs to your geojson, like so :
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
"6690861",
"682187"
]
},
"properties": {
"id": "908",
"message": "105",
"date": "",
"place": "",
"shape": ""
},
"crs": {
"type": "name",
"properties": {
"name": "urn:ogc:def:crs:EPSG::3857"
}
}
}
Also, I think it's
L.Proj.geoJson(data).addTo(map);
instead of
L.geoJson(data).addTo(map);
I tried L.geoJson on my code and it didn't show anything contrary to L.Proj.geoJson so it might be your problem here.
Related
I'm working with leaflets and I've noticed that many examples use a separate js file where a variable is set to a JSON stream.
How would I be able to modify the following example so that it can read off a json file with the geojson and not have the variable declaration in the javascript?
The code looks like this:
<script type="text/javascript">
var geoJsonData = {
"type": "FeatureCollection",
"features": [
{ "type": "Feature", "id":"1", "properties": { "address": "2" }, "geometry": { "type": "Point", "coordinates": [175.2209316333,-37.8210922667 ] } },
{ "type": "Feature", "id":"2", "properties": { "address": "151" }, "geometry": { "type": "Point", "coordinates": [175.2238417833,-37.80975435 ] } },
{ "type": "Feature", "id":"3", "properties": { "address": "21" }, "geometry": { "type": "Point", "coordinates": [175.2169955667,-37.818193 ] } },
{ "type": "Feature", "id":"4", "properties": { "address": "14" }, "geometry": { "type": "Point", "coordinates": [175.2240856667,-37.8216963 ] } },
{ "type": "Feature", "id":"5", "properties": { "address": "38B" }, "geometry": { "type": "Point", "coordinates": [175.2196982333,-37.8188702167 ] } },
{ "type": "Feature", "id":"6", "properties": { "address": "38" }, "geometry": { "type": "Point", "coordinates": [175.2209942 ,-37.8192782833 ] } }
]
};
var tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 18,
attribution: '© OpenStreetMap contributors'
});
var map = L.map('map')
.addLayer(tiles);
var markers = L.markerClusterGroup();
var geoJsonLayer = L.geoJson(geoJsonData, {
onEachFeature: function (feature, layer) {
layer.bindPopup(feature.properties.address);
}
});
markers.addLayer(geoJsonLayer);
map.addLayer(markers);
map.fitBounds(markers.getBounds());
</script>
I know it can be done with $.getJSON, but I would prefer using L.geoJson, if possible.
To read JSON data from a file you can use the fetch function (read more).
Here is an example:
fetch('http://example.com/movies.json')
.then(function(response) {
return response.json();
})
.then(function(myJson) {
// Do something with the JSON data
console.table(myJson);
});
In your case:
function doSomething(geoJsonData) {
var tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 18,
attribution: '© OpenStreetMap contributors'
});
var map = L.map('map')
.addLayer(tiles);
var markers = L.markerClusterGroup();
var geoJsonLayer = L.geoJson(geoJsonData, {
onEachFeature: function (feature, layer) {
layer.bindPopup(feature.properties.address);
}
});
markers.addLayer(geoJsonLayer);
map.addLayer(markers);
map.fitBounds(markers.getBounds());
}
fetch('http://myserver.com/myfile.json')
.then(function(response) {
return response.json();
})
.then(doSomething)
.catch(function(err) {
// In case of error, display the error message
console.error(err);
});
Notice that I put your code inside a callback function, as the fetch function is asynchronous.
You can store the geoJSON variable in a separate .js file and import it into the main logic .js file. Try pasting your var geoJsonData in a file called geoJsonData.js, then at the bottom of that file add "module.exports = geoJsonData;". Then on your logic file (ie scripts.js), you can import the variable as is by adding "var geoJsonData = require("./geoJsonData.js"); at the top. Then your call to add the points to the map would be
function geoJsonMarkers() {
$.getJSON(geoJsonData, function (data) {
// this adds the GeoJSON layer to the map once the file is loaded
L.geoJson(data).addTo(mymap);
}
}
I know it can be done with $.getJSON, but I would prefer using L.geoJson, if possible.
You seem to not realize that these 2 functions provide different steps of your workflow, as illustrated by the 2 other answers.
You may be misled by other libraries that provide utility functions which perform both steps for you.
jQuery's $.getJSON is to fetch / retrieve data from your server.
Once you have the resulting JS object, you feed it into Leaflet's L.geoJSON factory to have it converted into Leaflet layers.
Created some markers using an array of GeoJSON data:
$.getJSON("GetLocationsServlet", function(data) {
L.geoJSON(data, {
onEachFeature: onEachFeature
}).addTo(mymap);
});
The GeoJSON data is like this:
[
{ "type": "Feature", "properties": { "name": "Riverway Sport Complex", "amenity": "GYM", "popupContent": "Riverway Sport Complex" }, "geometry": { "type": "Point", "coordinates": [-123.002846, 49.205036] },"id" : "1"} ,
{ "type": "Feature", "properties": { "name": "Imperial#Patterson", "amenity": "GYM", "popupContent": "Imperial#Patterson" }, "geometry": { "type": "Point", "coordinates": [-123.01249, 49.22193] },"id" : "2"}
]
The markers were successfully created and showed on the map. At some point later, I needed to iterate through all Markers, so I used eachLayer function:
var mymap = L.map('mapid').locate({setView: true, maxZoom: 15});
L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png? '
access_token=..., {
maxZoom: 25,
attribution:
id: 'mapbox.streets',
}).addTo(mymap);
.......
$.getJSON( L.geoJSON()... )
.......
mymap.eachLayer(function(layer) {
alert (layer.options.id);
// Above alert successfully print out the tileLayer ID
if (layer instanceof L.Marker) {
alert("Marker [" + layer.options.title + "]");
}
});
However, it only looped through the main map tileLayer and stopped.
Am I using the eachLayer method correctly? Marker is also a subclass of Layer?
Thanks,
I am trying to show clusters using markerclustergroups with Polygons. Right now the polygons are shown but the clusters aren't. I have been trying to use center of mass for the polygons because it seems like markerclustergroup doesn't like polygons but that doesn't really work since the animation of markerclustergroup will be set on the centroids and not the actual polygon.
My polygons all vary in amount of coordinates. Some have +10 sets others have 3.
How would I use markerclustergroup for polygons?
Below my code can be seen:
// Create variable to hold map element, give initial settings to map
var map = L.map('map', {
center: [23.70489, 43.90137],
zoom: 5
});
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
}).addTo(map);
var ojStyle = {
"color": "#ff7800",
"weight": 5,
"opacity": 0.65
};
// Hardcoded polygons as GeoJSON
var polygons = {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[37.99896240234376, 21.55017532555692],
[39.39422607421876, 21.476073444092435],
[38.88336181640626, 22.56582956966297],
[38.023681640625, 22.611475436593366],
[37.43591308593751, 21.99908185836153],
[37.28485107421876, 21.624239377938288],
[37.28485107421876, 21.624239377938288],
[37.99896240234376, 21.55017532555692]
]
]
}
}, {
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[38.50708007812501, 21.453068633086783],
[39.20745849609376, 21.37124437061832],
[39.10858154296876, 20.876776727727016],
[38.80920410156251, 20.912700155617568],
[38.49884033203126, 20.94604992010052],
[38.50708007812501, 21.453068633086783]
]
]
}
}, {
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[50.57830810546875, 25.980268007469803],
[50.77606201171876, 25.956809920555312],
[50.780181884765625, 25.69970044378398],
[50.56457519531251, 25.822144306879686],
[50.56182861328126, 25.945696562830516],
[50.57830810546875, 25.980268007469803]
]
]
}
}, {
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[54.37408447265626, 24.51963836811676],
[54.29443359375001, 24.40963901896311],
[54.25872802734375, 24.449649897759667],
[54.32739257812501, 24.539627918861232],
[54.37133789062501, 24.559614286039903],
[54.37408447265626, 24.51963836811676]
]
]
}
}, {
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[54.40155029296876, 24.463400705082282],
[54.41940307617188, 24.489648077028683],
[54.45785522460938, 24.462150693715266],
[54.43450927734376, 24.43839812102505],
[54.40155029296876, 24.463400705082282]
]
]
}
}]
}
var polygonArray = []
for (i = 0; i < polygons.features.length; i++) {
polygonArray.push(polygons.features[i]);
}
var markers = L.markerClusterGroup().addTo(map);
var geoJsonLayer = L.geoJson(polygonArray);
markers.addLayer(geoJsonLayer);
map.fitBounds(markers.getBounds());
http://js.do/code/165930 - Shows how clustering doesn't work for the polygons
I am looking for a solution like this: http://jsfiddle.net/ve2huzxw/237/
You can do it very much like in this GIS post: Is it possible to cluster polygons in Leaflet?
// Compute a polygon "center", use your favourite algorithm (centroid, etc.)
L.Polygon.addInitHook(function() {
this._latlng = this._bounds.getCenter();
});
// Provide getLatLng and setLatLng methods for
// Leaflet.markercluster to be able to cluster polygons.
L.Polygon.include({
getLatLng: function() {
return this._latlng;
},
setLatLng: function() {} // Dummy method.
});
Updated live example: http://js.do/code/166021
Updated with a JSFIDDLE link
I am using LeafletJS to build a web map with a timeline slider. I am using the LeafletSlider plugin to show a group of markers based on a GEOJSON property named DATE_START. Here's an example of what my data object looks like:
var camps = {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"properties": {
"STATUS": "UNOCCUPIED",
"DATE_START": "2015-06-23",
"DATE_CLOSED": "2016-01-23"
},
"geometry": {
"type": "Point",
"coordinates": [64.6875, 34.97600151317591]
}
}, {
"type": "Feature",
"properties": {
"STATUS": "OCCUPIED",
"DATE_START": "2014-01-21",
"DATE_CLOSED": "2015-05-25"
},
"geometry": {
"type": "Point",
"coordinates": [65.335693359375, 36.26199220445664]
}
}, {
"type": "Feature",
"properties": {
"STATUS": "UNOCCUPIED",
"DATE_START": "2015-09-13",
"DATE_CLOSED": ""
},
"geometry": {
"type": "Point",
"coordinates": [67.587890625, 35.969115075774845]
}
}]
};
An example of my code:
//Create a marker layer (in the example done via a GeoJSON FeatureCollection)
var testlayer = L.geoJson(camps, {
onEachFeature: function(feature, layer) {
layer.bindPopup(feature.properties.DATE_START);
}
});
var sliderControl = L.control.sliderControl({
position: "topright",
layer: testlayer,
timeAttribute: 'DATE_START'
});
//Make sure to add the slider to the map ;-)
map.addControl(sliderControl);
//And initialize the slider
sliderControl.startSlider();
I've added the timeslider plugin to my map, and although it's functioning, I can't seem to get the slider to show the markers in a temporal order. For example, the marker with the DATE_START value of 2014-01-21 is shown second when in fact it should be shown first because it's the marker with the earliest date.
How can I get my timeslider/markers to appear in the correct order from earliest to latest? Thanks.
EDIT:
As ghybs mentions below (and shows in an example), the proper way to ensure that the slider returns data in the correct order is to sort the options.markers array of the sliderControl:
sliderControl.options.markers.sort(function(a, b) {
return (a.feature.properties.DATE_START > b.feature.properties.DATE_START);
});
My original answer (below) sorts the features of the GeoJSON, but this does not guarantee that Leaflet will return them in the correct order.
Original answer:
You can use the array.sort method to sort the features array in place:
camps.features.sort(function(a, b) {
return (a.properties.DATE_START > b.properties.DATE_START);
});
http://jsfiddle.net/nathansnider/ngeLm8c0/4/
I have this html:
<div id="clickthis"><p>addGeoJSON</p></div>
<div id='raw'></div>
<div id='map'></div>
and this is my javascript code:
var geojson = [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-77.03238901390978,38.913188059745586]
},
"properties": {
"title": "Mapbox DC",
"description": "1714 14th St NW, Washington DC",
"marker-color": "#fc4353",
"marker-size": "large",
"marker-symbol": "monument"
}
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-122.414, 37.776]
},
"properties": {
"title": "Mapbox SF",
"description": "155 9th St, San Francisco",
"marker-color": "#fc4353",
"marker-size": "large",
"marker-symbol": "harbor"
}
}
];
L.mapbox.accessToken = 'pk.eyJ1IjoibWFwcGllc3RpY2tlciIsImEiOiJIn0.IgCoorxIUvE0CjcPriROeQ';
var map = L.mapbox.map('map', 'mappiesticker.kh78ogof').setView([34, -118.50], 9);
$('#clickthis').click(function(){
alert('alkr');
dataLayer = L.mapbox.featureLayer(geojson);
dataLayer.addTo(map);
})
The alert fires when I click that div, but nothing else happens. I tried using the .setGeoJSON function but it returned undefined. I concluded that thats only used when you are creating the map, not adding GeoJSON after its creation
I'm getting a 401 error when using your token:
Failed to load resource: the server responded with a status of 401 (Unauthorized)
When i use your code with Mapbox's example token and map (note, you should be using your own token and map) it's perfectly fine:
L.mapbox.accessToken = 'pk.eyJ1IjoicGF1bC12ZXJob2V2ZW4iLCJhIjoiZ1BtMWhPSSJ9.wQGnLyl1DiuIQuS0U_PtiQ';
var map = L.mapbox.map('mapbox', 'examples.map-i86nkdio', {
'center': [0, 0],
'zoom': 1
});
Working example on Plunker: http://plnkr.co/edit/wrlC7AAHLBWsDgzk8PRw?p=preview
I'de double check your accounttoken and map id.