Is it possible in leaflet to drop marker with 3857 projection on map?
I fond a solution where first translate point to 4326 using proj4js and than drop it on map.
var source = new Proj4js.Proj('EPSG:3857');
var dest = new Proj4js.Proj('EPSG:4326');
var p = new Proj4js.Point(-12307.601047734, 6711475.1283642);
Proj4js.transform(source, dest, p);
new L.Marker([p.y, p.x], {bounceOnAdd: true}).addTo(map);
is there any other way in core leaflet or leaflet plugin to drop marker without using proj4js library.
Thanks.
After spending good time on internet.i'm finally done it.
var point = new L.Point(-12307.601047734, 6711475.1283642);
var earthRadius = 6378137;
var latlng = L.Projection.SphericalMercator.unproject(
point.divideBy(earthRadius));
new L.Marker([latlng.lat, latlng.lng], {bounceOnAdd: true}).addTo(map);
Same code into a reusable function:
L.CRS.EPSG3857.unproject = function (point) { // (Point) -> LatLng
var earthRadius = 6378137,
normalizedPoint = point.divideBy(earthRadius);
return this.projection.unproject(normalizedPoint);
}
Use it like:
var latlng = L.CRS.EPSG3857.unproject(point);
Example:
var point = new L.Point(-12307.601047734, 6711475.1283642);
L.marker(L.CRS.EPSG3857.unproject(point), {bounceOnAdd: true}).addTo(map);
Related
I'm trying to create a straight line network in Leaflet, which at each junction has a marker, and on drag of each marker, update the position of the corresponding polyline which connects to it.
I've done some research (mostly this question) & reworked a fiddle to strip it down a bit to try & get it to do what I want. I am able to draw the network with individual polylines, however, I need to add multiple parentLines to the marker which is connected to two polylines. I can't find it in the Leaflet documentation, but punted with this:
marker_arr[1].parentLine = [polyline_a,polyline_b];
My issue is when I call the dragstart/drag/dragend handlers, it doesn't work with multiple polylines. (Edit) I have made some headway in capturing the parentLines as an array, but can only make it work for the first parentLine
function dragHandler(e) {
var polyline=[]
console.log("drag")
if(e.target.parentLine.length){
polyline.push(e.target.parentLine[0]);
} else {
polyline.push(e.target.parentLine);
}
if(polyline){
var latlngPoly = polyline[0].getLatLngs(), // Get the polyline's latlngs
latlngMarker = this.getLatLng(); // Get the marker's current latlng
latlngPoly.splice(this.polylineLatlng, 1, latlngMarker); // Replace the old latlng with the new
polyline[0].setLatLngs(latlngPoly); // Update the polyline with the new latlngs
}
}
Can anyone point me to either the documentation about parentLine, or how I might make this work? Using Leaflet v1.6.0 and cannot use more recent versions as this is to extend an already existing implementation of Leaflet based on 1.6.
Fiddle here
Here is a sample.
Add to the marker the parentLines always as array:
marker_arr[0].parentLine = [polyline_a];
marker_arr[1].parentLine = [polyline_a,polyline_b];
marker_arr[2].parentLine = [polyline_b];
and then loop through all parentLines in the dragstart handler:
// Now on dragstart you'll need to find the latlng from the polyline which corresponds
// with your marker's latlng and store it's key in your marker instance so you can use it later on:
function dragStartHandler(e) {
var marker = e.target;
marker.polylineLatlng = {};
e.target.parentLine.forEach((line)=>{
var latlngPoly = line.getLatLngs(), // Get the polyline's latlngs
latlngMarker = marker.getLatLng(); // Get the marker's current latlng
for (var i = 0; i < latlngPoly.length; i++) { // Iterate the polyline's latlngs
if (latlngMarker.equals(latlngPoly[i])) { // Compare marker's latlng ot the each polylines
marker.polylineLatlng[L.stamp(line)] = i; // If equals store key in marker instance
}
}
})
}
And in the drag handler:
// Now you know the key of the polyline's latlng you can change it
// when dragging the marker on the dragevent:
function dragHandler(e) {
var marker = e.target;
e.target.parentLine.forEach((line)=>{
var latlngPoly = line.getLatLngs(), // Get the polyline's latlngs
latlngMarker = marker.getLatLng(); // Get the marker's current latlng
latlngPoly.splice(marker.polylineLatlng[L.stamp(line)], 1, latlngMarker); // Replace the old latlng with the new
line.setLatLngs(latlngPoly); // Update the polyline with the new latlngs
})
}
And clean it in the dragend handler:
// Just to be clean and tidy remove the stored key on dragend:
function dragEndHandler(e) {
var marker = e.target;
delete marker.polylineLatlng;
console.log("end");
}
Basically, I just want to plot a circle, at a user defined lat/lon with a radius of X km.
So I realize looking through documentation, I can't change the lat/lons of the mappolygons that are already loaded through the geodata, but I guess I'm not quite sure how to create a new map polygon with a specified lat/lon or if I can even do that!
My code is set up so that everytime the user clicks somewhere a marker is plotted or replotted accordingly, the location of the marker is where I would like to plot the center of the circle. I get that using the getCircle function I need to do the whole km2deg for the third variable, but I'm more concerned with the location right now. Any help would be great!
https://codepen.io/kbreezy/pen/wLRrPq
below is my onclick method of the code.
chart.seriesContainer.events.on("hit", function(ev) {
var lp = $("#chartdiv").data("point");
var coords = chart.svgPointToGeo(ev.svgPoint);
if (lp) {
lp.latitude = coords.latitude;
lp.longitude = coords.longitude;
} else {
var marker = imageSeries.mapImages.create();
marker.latitude = coords.latitude;
marker.longitude = coords.longitude;
}
$("#chartdiv").data("point", marker);
var circleSeries = chart.series.push(new am4maps.MapPolygonSeries())
var circleTemplate = circleSeries.mapPolygons.template;
circleTemplate.fill = am4core.color("#bf7569");
circleTemplate.strokeOpacity = 1;
circleTemplate.fillOpacity = 0.75;
var polygon = circleSeries.mapPolygons.create();
var mapPolygon = polygonSeries.getPolygonById("DE");
mapPolygon.setPropertyValue('latitude', coords.latitude);
mapPolygon.setPropertyValue('longitude', coords.longitude);
polygon.latitude = coords.latitude;
polygon.longitude = coords.longitude;
polygon.multiPolygon = am4maps.getCircle(mapPolygon.visualLongitude, mapPolygon.visualLatitude, 5);
//polygon.multiPolygon = am4maps.getCircle(coords.latitude, coords.longitude, 5);
});
MapPolygon does not have some latitude/longitude where you could "move" it. It's multipolygon must contain coordinates of the area you want to show. So when you pass longitude/latitude to the getCircle method, it returns multiPolygon around that point.
I modified your pen where to show the concept: https://codepen.io/team/amcharts/pen/ydrLZw
polygon.multiPolygon = am4maps.getCircle(coords.longitude, coords.latitude, 5);
I'd like to get the coordinates of map bounds as a list of 4 floats (i.e. two points in latitude/longitude coordinates).
This (Google maps undocumented feature) used to work until a few days ago:
var b = map.getBounds();
var bounds = [b.H.H, b.H.j, b.j.j, b.j.H];
It doesn't work anymore. How to get these 4 floats ?
function getRectFromBounds(bounds) {
var ne = bounds.getNorthEast();
var sw = bounds.getSouthWest();
return [ne.lat(), ne.lng(), sw.lat(), sw.lng()];
};
var rect = getRectFromBounds(map.getBounds());
you can extend LatLngBounds and create a utility function to return this array, something like map.getBounds().toRect()
I have a simple map with 17 points (GeoJSON) in leaflet, and using the draw tool, I create a polygon to use to select the points within th polygon.
map.on('draw:created', function (e) { //from draw tool
var type = e.layerType,
layer = e.layer;
editableLayers.addLayer(layer);
GetSelection(editableLayers);
});
function GetSelection(layer){
var count = allPoints.getLayers().length;
console.log(count +" Sites"); //says 17
var drawList = editableLayers.getLayers().length;
console.log(drawList +" Polys"); //Says 1
if (editableLayers.getLayers().length >0){
var fcpt = turf.featurecollection(allPoints);
console.log(fcpt); // says 17
var fcpoly = turf.featurecollection(editableLayers);
console.log(fcpoly); // fails as undefined
//var ptsWithin = turf.within(fcpt,editableLayers);
var ptsWithin = turf.within(fcpt,fcpoly);
console.log(ptsWithin); //never gets this far.
};
};
Any ideas or suggestions?
turf.featurecollection expects an array of GeoJSON Features, not a Leaflet Layer Group like your allPoints and editableLayers variables.
Similarly, turf.within expects 2 GeoJSON Feature Collections as arguments, not Leaflet Layer Groups.
So you could probably try directly:
var ptsWithin = turf.within(allPoints.toGeoJSON(), editableLayers.toGeoJSON());
#ghybs was right, it was a difference between Leaflet and turf, while the points were OK, the polygon did not come over. Passing turf the GeoJson the polygon info allowed it to work.
Working copy:
map.on('draw:created', function (e) {
featureGroup.clearLayers();
layer = e.layer;
featureGroup.addLayer(layer);
GetSelection(featureGroup);
});
function GetSelection(layer){
var shape2 = allPoints.toGeoJSON() //All facilities
var ptsWithin = turf.within(shape2, layer.toGeoJSON());
alert('Found ' + ptsWithin.features.length + ' features');
alert("results "+JSON.stringify(ptsWithin));
};
Despite spending all day searching and trying numerous code methods I am still having problems with trying to center and zoom a google map correctly.
I wonder if someone would be so kind as to point out the obvious as to what Im doing wrong in my code. Everything worked fine in v2 but Im having difficulty updating to v3.
For information
The map is a small part of a much larger php application, and the needed lat & long map parameters have already been obtained by other methods which are used in the main prog and declared as follows:-
var myDestination=new google.maps.LatLng(e_lat,e_long);
var myHome=new google.maps.LatLng(h_lat,h_long);
Everything seems to be working ok aside from the zoom and center.
Problematic Code is as follows:-
function initialize()
{
// set the map properties
var mapProp = {
center:myHome,
zoom:12,
mapTypeId:google.maps.MapTypeId.ROADMAP
};
var map=new google.maps.Map(document.getElementById("googleMap"),mapProp);
// set the home marker
var marker_home=new google.maps.Marker({
position:myHome,
icon:'house.png'
});
marker_home.setMap(map);
//set the destination marker
var marker_destination=new google.maps.Marker({
position:myDestination,
icon:'flag_red.png'
});
marker_destination.setMap(map);
//google polyline between the 2 points
var myPolyline = [myDestination,myHome];
var directPath = new google.maps.Polyline({
path:myPolyline,
strokeColor:"#0000FF",
strokeOpacity:0.8,
strokeWeight:2
});
directPath.setMap(map);
// Make an array of the LatLng's of the markers you want to show
var LatLngList = array (new google.maps.LatLng (e_lat,e_long), new google.maps.LatLng (h_lat,h_long));
// Create a new viewpoint bound
var bounds = new google.maps.LatLngBounds ();
// Go through each...
for (var i = 0, LtLgLen = LatLngList.length; i < LtLgLen; i++) {
// And increase the bounds to take this point
bounds.extend (LatLngList[i]);
}
// Fit these bounds to the map
map.fitBounds (bounds);
}
google.maps.event.addDomListener(window, 'load', initialize);
TIA for any help :)
In your code "array" is not defined. See jsFiddle.
var LatLngList = array (new google.maps.LatLng (e_lat,e_long), new google.maps.LatLng (h_lat,h_long));
You should use
var LatLngList = new Array(new google.maps.LatLng...)
or
var LatLngList = [new google.maps.LatLng...]