Leaflet map with Socrata open data with lat/lng in a combined geom point column? - leaflet

I learned how to create a Leaflet map with Socrata open data when latitude and longitude appear in separate columns. See working examples at https://github.com/JackDougherty/leaflet-socrata
My problem: how to make this work when latitude and longitude are combined in one point data field (geom) inside Socrata? This is common for datasets published on http://data.hartford.gov. See my non-working example at https://github.com/JackDougherty/leaflet-socrata
Solved with this code snippet:
// load open data from Socrata endpoint in GeoJSON format
// Food Establishments, City of Hartford Open Data https://data.hartford.gov/resource/daux-ukcc
$.getJSON("https://data.hartford.gov/resource/daux-ukcc.geojson", function (data){
var geoJsonLayer = L.geoJson(data, {
pointToLayer: function( feature, latlng) {
var marker = L.marker(latlng);
marker.bindPopup(feature.properties.blms_dba); // replace last term with property data labels to display from GeoJSON file
return marker;
}
}).addTo(map);
});
See my notes and more examples at https://www.datavizforall.org/leaflet/with-socrata/

Related

Copy-Paste data of one polygon to another, LEAFLET

I have a Polygon Layer in Leaflet. Each polygon have an unique ID.
Is there any possibility to copy data from one polygon to another*except ID?
var poly1 = L.polygon(latlngs, options);
var copyPoly = L.polgygon(poly1.getLatLngs(),poly1.options);
// copyPoly.options.uiqueId = newId; // when the Id is stored in the options
If this is not working, share your code with us

How to change the color of results from leaflet-knn on the map

I have displayed the the result markers for the leaflet-knn on the map with following code:
const myloc = new L.LatLng(13.7433242, 100.5421583);
var gjLayer = L.geoJson(testCities, {
onEachFeature: function(feature, layer) {
content = "<b>Name:</b> " + feature.properties.name;
layer.bindPopup(content);
}
});
var longitude = myloc.lng,
latitude = myloc.lat;
var res = leafletKnn(gjLayer).nearest(
[longitude, latitude], 5, distance);
for (i = 0; i < res.length; i++) {
map.addLayer(res[i].layer);
}
Now I want to change the color of this marker that is added or I want to change the icon.
Can anybody tell me how can I do?
Leaflet-knn is agnostic when it comes to the representation of the results - it relies on the existing L.Layers: it takes a L.GeoJSON as an input and then iterates through all its members in order to fetch all their coordinates (in the case of polylines and polygons) and then store a reference to the L.Layer for each of its coordinates.
The results of a leaflet-knn search include the original L.Layer from the L.GeoJSON that was passed at instantiation time.
Either symbolize your GeoJSON afterwards, as explained in the Leaflet tutorials, or create new markers/symbols for the results after each query.
Right now your code is relying on the default symbolization of GeoJSON data (instantiate a L.Marker with a L.Icon.Default for points). I suggest the approach of displaying your L.GeoJSON in the map to ensure that it looks like you want it to (even if it's a partial set of the data), then implementing the leaflet-knn search.

Mapbox: Filtering out markers in a Leaflet Omnivore KML layer

I am exporting Google Directions routes as KML and displaying them on a Mapbox map by reading them with Omnivore and adding them to the map,
The Google KML stores each route as two Places (the start and end points) and one LineString (the route). In Mapbox I would like to show only the routes, that is to filter out the markers somehow. I'm displaying markers out of my own database and the Google markers clutter it up.
Here is my code. I change the styling of the LineStrings just to show that I can, but do not know what magic call(s) to make to not display the Points.
Thanks.
runLayer = omnivore.kml('data/xxxx.kml')
.on('ready', function() {
var llBnds = runLayer.getBounds();
map.fitBounds(llBnds);
this.eachLayer(function (layer) {
if (layer.feature.geometry.type == 'LineString') {
layer.setStyle({
color: '#4E3508',
weight: 4
});
}
if (layer.feature.geometry.type == 'Point') {
//
// Do something useful here to not display these items!!
//
}
});
})
.addTo(map);
Welcome to SO!
Many possible solutions:
Most straight forward from the code you provided, just use the removeLayer method on your runLayer Layer Group when you get a 'Point' feature.
Cleaner solution would be to filter out those features before they are even converted into Leaflet layers, through a custom GeoJSON Layer Group passed as 3rd argument of omnivore.kml, with a specified filter option:
var customLayer = L.geoJSON(null, {
filter: function(geoJsonFeature) {
// my custom filter function: do not display Point type features.
return geoJsonFeature.geometry.type !== 'Point';
}
}).addTo(map);
var runLayer = omnivore.kml('data/xxxx.kml', null, customLayer);
You can also use the style and/or onEachFeature options on customLayer to directly apply your desired style on your LineString.

Editing/Removing GeoJSON layers from a featureGroup in Mapbox using Leaflet

I'm using Mapbox with Leaflet for drawing, editing and removing polygons etc. Every time I create a new polygon, I convert them to a GeoJSON layer and then add it to the featureGroup that I created, because I want to associate each layer with an ID property that I can use later. This is what I have:
var featureGroup = L.featureGroup().addTo(map);
var drawControl = new L.Control.Draw({
edit: {
featureGroup: featureGroup
},
draw: {
polygon: {
allowIntersection: false
},
polyline: false,
rectangle: false,
circle: false,
marker: false
}
}).addTo(map);
map.on('draw:created', addPolygon);
map.on('draw:edited', editPolygon);
map.on('draw:deleted', deletePolygon);
function deletePolygon(e) {
featureGroup.removeLayer(e.layer);
}
function editPolygon(e) {
featureGroup.eachLayer(function (layer) {
layer.eachLayer(function (layer) {
addPolygon({ layer: layer });
});
});
}
function addPolygon(e) {
var geojsonstring = e.layer.toGeoJSON();
var geojson = L.geoJson(geojsonstring);
featureGroup.addLayer(geojson);
}
When I do this, creating polygons is not a problem. But when I try to edit or delete polygons, it doesn't work properly.
When I try to edit a polygon, it tells me "TypeError: i.Editing is undefined". It doesn't allow me to cancel editing as well.
When I try to delete a polygon, it is not displayed in the map anymore, but it is still not removed from the featureGroup.
What am I doing wrong here?
Edit: The way I'm currently doing this is the same way that ghybs has suggested. But the problem is, once all the edits are done, the polygons are saved to a database (I convert it to a WKT string to save in SQLServer). And when the page is loaded the next time, the polygons are loaded back from the database, and the user can edit or delete them and save it back to the database.
As it is right now, when the user makes the edit and saves them again, it only creates duplicate polygons. and I don't know of any way to connect the edited polygons to the ones from the database.
So I thought if I could convert them to GeoJSON and assign an ID property to each layer (something like ID=0 if it is a new layer, and the corresponding polygonID from the database if it is loaded from the database). So that when they are saved again, I can check this ID and based on that, I can either update the available polygon, or create a new polygon in the database.
Is there a better way of doing this?
Not sure exactly why in addPolygon you go through a GeoJSON object that you convert back into a Leaflet layer group through L.geoJson?
You could have directly added the created layer, as in Leaflet.draw "draw:created" example:
function addPolygon(e) {
var layer = e.layer;
var feature = layer.feature = layer.feature || {}; // Initialize layer.feature
// use the feature.id: http://geojson.org/geojson-spec.html#feature-objects
feature.id = 0; // you can change it with your DB id once created.
featureGroup.addLayer(layer);
// record into DB, assuming it returns a Promise / Deferred.
recordToDb(layer.toGeoJSON()).done(function (result) {
feature.id = result.id; // Update the layer id.
});
}
As for the reason for you error, it is due to the fact that you add a (GeoJSON) Layer Group to your featureGroup, which Leaflet.draw plugin does not know how to handle. You must add only "non group" layers.
See also: https://gis.stackexchange.com/questions/203540/how-to-edit-an-existing-layer-using-leaflet

Start-Marker from geojson polyline

i have a map with some walking- and bike-routes and popups with a few details an a pic. Now i want to set a marker on the first vertex of a geojson polyline, but i cant find out how. Btw. i´m new to leaflet/mapbox, and i put my map togehter from code snippets.
Here is the map now:
This is how i create the polylines now. I call them via layercontrol.
var mtb = L.geoJson(radjs, {
filter: function (feature, layer) {
if (feature.properties) {
// If the property "underConstruction" exists and is true, return false (don't render features under construction)
return feature.properties.typ === 'mtb';
}
return true;
},
style: {
"color": '#6699cc',
dashArray: '',
"weight": 4,
"opacity": 0.6
}, onEachFeature: onEachFeature2}).addTo(rad);
Thank you for your help,
Marc
You could just add a Feature to your geojson with the latitude and longitude like the do it in the Leaflet GeoJSON Example.
Probably it will be more convenient to read the geometry.coordinates from geojson features and define a new marker.
Beside you have an error on line 569. You should change:
var map = L.mapbox.map('map','',{
to:
var map = L.mapbox.map('map',null,{
Create a simple marker object and add it to the map.
marker = L.marker([0, 0], {
icon: L.mapbox.marker.icon()
}).addTo(map)
Then set the latitude and longitude to the first coordinates of your geoJSON. Assuming your geoJSON is set to the var geojson, you can access the coordinates by indexing into the array.
marker.setLatLng(L.latLng(
geojson.coordinates[0][1],
geojson.coordinates[0][0]))