Start-Marker from geojson polyline - leaflet

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]))

Related

Polygon on Bing Map using Local GeoJSON Object results in wrong location

Im using Bing Map v8 to draw a polygon on a map.
for some reason, two different methods for doing so results in different results even though im using the same coordinates.
This method
as shown here
works well:
map = new Microsoft.Maps.Map(document.getElementById("map"), {
credentials: '',
mapTypeId: Microsoft.Maps.MapTypeId.aerial,
});
var polygon = new Microsoft.Maps.Polygon([
new Microsoft.Maps.Location(32.57922,34.91395),
new Microsoft.Maps.Location(32.53799,34.9021),
new Microsoft.Maps.Location(32.53264,34.91292),
new Microsoft.Maps.Location(32.55398,34.92339),
new Microsoft.Maps.Location(32.57156,34.93489),
new Microsoft.Maps.Location(32.57503,34.92614)],
{ fillColor: 'rgba(241, 227, 100, 0.3)', strokeColor: 'rgba(241, 227, 100, 0.8)', strokeThickness: 1 });
map.entities.push(polygon);
When using this Microsoft.Maps.GeoJson.read method as shown here to read a GeoJson object with the same polygon coordinates, the polygon is being drawn in an area hundreds of miles north-west from the original location. why is that ?
map = new Microsoft.Maps.Map(document.getElementById("map"), {
credentials: '',
mapTypeId: Microsoft.Maps.MapTypeId.aerial,
});
//define polygon using GeoJson Object
var GeoJson = {
"type": "Polygon",
"coordinates": [[
[32.57922,34.91395],
[32.53799,34.9021],
[32.53264,34.91292],
[32.55398,34.92339],
[32.57156,34.93489],
[32.57503,34.92614]
]]
};
//Load the GeoJson Module.
Microsoft.Maps.loadModule('Microsoft.Maps.GeoJson', function () {
//Parse the GeoJson object into a Bing Maps shape.
var shape = Microsoft.Maps.GeoJson.read(GeoJson, {
polygonOptions: {
fillColor: 'rgba(255,0,0,0.5)',
strokeColor: 'rgba(241, 227, 100, 0.8)',
strokeThickness: 1
}
});
//Add the shape to the map.
//results in wrong location !
map.entities.push(shapeA);
});
Bing Maps Locations take in latitude,longitude, while GeoJSON positions/coordinates are longitude/latitude. Reverse the numbers in your GeoJSON coordinates.

Show geojson featureCollection with Leaflet

with QGIS I´ve exported a polygon layer as geojson which I´d like to publish with leaflet. This is how the geojson looks like [exluded due to SO character limits]:
https://gist.github.com/t-book/88806d12d7f05024b147715be82e6844
This is what I´ve tried:
Wrapped geojson as var:
var states = [{
"type": "FeatureCollection",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:EPSG::31468" } },
"features": [
{ "type": "Feature", "properties": ...
}];
Added as new Layer:
L.geoJSON(states, {
style: function(feature) {
switch (feature.properties.party) {
case 'Euerbach': return {color: "#ff0000"};
case 'Werneck': return {color: "#0000ff"};
}
}
}).addTo(map);
Unfortunately nothing is rendered. How do I correctly add this geojson featureCollection to my map?
The problem is that your data is projected - Leaflet is expecting your data to be unprojected (composed of long/lat pairs, or "projected" in WGS84/EPSG 4326). There are a few solutions, two come to mind here:
In QGIS, export your data so that it is composed of long/lat coordinate pairs
Use proj4.js to reproject your coordinates when displaying the geojson.
For number two, you'll need to set the coordsToLatLng option when adding the geojson as a layer:
var geojson = L.geoJSON(states, {
coordsToLatLng: function (p) {
// return get lat/lng point here.
})
The body of this function will take a coordinate in the geojson's coordinate reference system (CRS) and return it in WGS84 using proj4.
Also, coordsToLatLng function expects you to return lat/long pairs. As your geojson and proj4 represent data that is [x,y], we need to swap our values before returning the new point.
This could look like:
var geojson = L.geoJSON(states, {
coordsToLatLng: function (p) {
p = proj4(fromProjection,toProjection,p); // reproject each point
p = [p[1],p[0]] // swap the values
return p; // return the lat/lng pair
}
}).addTo(map);
Of course, we need to define our CRSs. I looked up your CRS (it is specified in the geojson itself) on spatialreference.org and used the provided description for that CRS and EPSG4326 (WGS84) to set my fromProjection and toPojection:
var fromProjection = '+proj=tmerc +lat_0=0 +lon_0=12 +k=1 +x_0=4500000 +y_0=0 +ellps=bessel +datum=potsdam +units=m +no_defs ';
var toProjection = "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs ";
Altogether that gives us something like this.
Keep in mind, that if you have large files, reprojecting them in javascript will take longer than if you export them in the proper CRS.

Mapbox GL JS: zoom to filtered polygon?

I am using Mapbox GL JS to display a polygon layer. I would to allow the user to choose a name from a dropdown, and then highlight and zoom to the matching polygon.
I already know how to highlight the matching polygon using map.setFilter, but I don't know how to zoom to the bounds of the matching polygon. This is my current code:
map.addLayer({
'id': 'polygon_hover',
'source': 'mysource',
'source-layer': 'mylayer',
'type': 'fill',
'paint': {
'fill-color': 'red',
"fill-opacity": 0.6
},
"filter": ["==", 'CUSTNAME', ""]
});
// Get details from dropdown
custname.on("change", function(e) {
// get details of name from select event
map.setFilter('polygon_hover', ["==", 'CUSTNAME', name]);
// Get bounds of filtered polygon somehow?
// var bounds = ??;
// map.fitBounds(bounds);
});
I have examined the Mapbox example of zooming to bounds, but it assumes that you already know what the bounds are.
Is there any way it's possible to get the bounds of the polygon matching a map filter in Mapbox?
I've the following code to fitBounds to Polygon center coords:
var coordinates = f.geometry.coordinates[0];
var bounds = coordinates.reduce(function (bounds, coord) {
return bounds.extend(coord);
}, new mapboxgl.LngLatBounds(coordinates[0], coordinates[0]));
map.fitBounds(bounds, {
padding: 20
});
Where f is one Feature.
I found a solution to your problem. Leaflet has a polygon Class which takes an Array of polygon coordinates and has a function called getBounds() that returns south west and north east bounds. However, Leaflet doesn't follow the convention of LngLat, its format is LatLng. Therefore, you have to switch it. I took an example out from Mapbox Show drawn polygon area, and added exactly what you're looking for.
var polygon = data.features[0].geometry.coordinates;
var fit = new L.Polygon(polygon).getBounds();
var southWest = new mapboxgl.LngLat(fit['_southWest']['lat'], fit['_southWest']['lng']);
var northEast = new mapboxgl.LngLat(fit['_northEast']['lat'], fit['_northEast']['lng']);
var center = new mapboxgl.LngLatBounds(southWest, northEast).getCenter();
// map.flyTo({center: center, zoom: 10});
map.fitBounds(new mapboxgl.LngLatBounds(southWest, northEast));
I see that the question is still relevant - I solved it making a separate request to the database containing all points of a given polygon and building bounds [[minLng, minLat], [maxLng, maxLat]].
All attempts to address geometry of already rendered or source features didn't work for me - most probably because Mapbox doesn't keep initial geoJSON in the tiles.

Icon url in mapbox

How to add a custom icon in mapbox?
var map = L.mapbox.map('map', 'mapbox.streets').setView([0, 0], 1);
var geojson = { type: 'LineString', coordinates: value};
var start = value[0];
var end = value[value.length-1];
geojson.coordinates.push((start,end).slice());
// Add this generated geojson object to the map.
L.geoJson(geojson).addTo(map);
// Create a marker and add it to the map.
var marker = L.marker(end, {
icon: L.mapbox.marker.icon({
"iconUrl": "https://www.mapbox.com/mapbox.js/assets/images/astronaut2.png"
})
}).addTo(map);
});
I can't able to add a custom icon in above code. Please help me..
Thanks.
First you will have to create a var, for example 'myIcon', then simply replace the iconUrl with a path that specifies the custom marker you want to use.
You can use the iconSize option to specify the size of your marker
You can use the iconAnchor option to specify which part of your masker should be placed on the latlng.
myIcon=L.icon({
iconUrl:'img/custom-marker.png',
iconSize: [25,30]
});
Then create the marker, set the lat lng where you want your marker to be placed. And specify the icon you want to use.
var Marker = new L.Marker ( latlng, {icon:myIcon});
Finally add your market to the map:
map.addlayer(Marker);

style a geojson point like a POI with leaflet/mapbox

I am using mapbox.js to render a mapbox map. I am trying to load geojson from my server that contain either a country polygon or a city coordinates (lon,lat).
I have been able to style the country polygons but not the city points/markers.
I am not able to modify the geojson to use mapbox simplestyle
Here is the code executed when the page loads (I changed the mapbox map ID):
var southWest = L.latLng(-90, -360), northEast = L.latLng(90, 360);
var bounds = L.latLngBounds(southWest, northEast);
var map = L.mapbox.map('map', 'MapboxMapID', { zoomControl: false, infoControl: true, detectRetina: true, maxBounds: bounds, minZoom: 2, legendControl: {position: 'topright'}});
new L.Control.Zoom({ position: 'bottomright' }).addTo(map);
map.fitBounds(bounds);
var locationsGroup = L.featureGroup().addTo(map);
and then when the user selects a country or city with a selectbox:
$("#select2-search-up").on("change", function (e) {
if (e.added) {
var location = L.mapbox.featureLayer().loadURL('/citiesCountriesID/' + e.added.id).on('ready', function(featLayer) {
this.eachLayer(function(polygon) {
polygon.setStyle({
stroke:false, fillColor:'red', fillOpacity:0.2
});
});
});
locationsGroup.addLayer(location);
} else {
locationsGroup.eachLayer(function (layer) {
if (layer._geojson[0]._id == e.removed.id) {
locationsGroup.removeLayer(layer);
}
});
}
});
Ideally I would like to display a different icon that the standard marker, but I could do with a small red square
Thank you for your inputs
In this example I did some circle markers but I'm pretty sure you can do other basic svg shps or your own .png pretty easy. http://bl.ocks.org/mpmckenna8/db2eef40314fe24e9177
This example from Mapbox also shows how to use a icon from their icon Library which has a lot of choices also. https://www.mapbox.com/mapbox.js/example/v1.0.0/l-mapbox-marker/
It might also help to see some of your geojson structure to see why it can't use simplestyle
In my bl.ocks example I loaded each of the geojson datasets separately
var begin = L.geoJson(start,{
pointToLayer:function(feature, latlng){
return L.circleMarker(latlng,{
radius:9,
fillColor: "orange",
fillOpacity:.7
})
}
})
Is how I set up my circles and I set a different L.geoJson to the other data which I left as the default markers.