Circle getBounds() method fails in Leaflet - javascript

I have:
const map = L.map("mapid", {preferCanvas: true});
//....
const circle = L.circle([47.6652642, -122.3161248], {
color: '#ea647f',
fillOpacity: 0.4,
radius: 30
}).addTo(map);
but calling getBounds() on circle fails:
const bounds = circle.getBounds();
It fails inside function getBounds in Circle.js which is Leaflet code,
The Leaflet getBounds method code is:
getBounds: function () {
var half = [this._radius, this._radiusY || this._radius];
return new LatLngBounds(
this._map.layerPointToLatLng(this._point.subtract(half)),
this._map.layerPointToLatLng(this._point.add(half)));
}
Trying to access this._map.layerPointToLatLng fails
I get the error that this._map is undefined
Any ideas?
===================================================
Please Note: I also have a polygon defined,
and calling the getBounds() on the polygon passes fine and works correctly, shows correctly on the map.
=> It is only the Circle.getBounds() that fails

Add center and zoom to the map.
const map = L.map("map", {center:[47.6652642, -122.3161248], zoom: 16 ,preferCanvas: true});

You need to initialise the map state with setView() or some other mechanism. The layerPointToLatLng calls will fail otherwise.

Related

Google Maps API use zoom level and center position from local storage values to adjust map on page load

I am working with a WordPress/jQuery/Google Maps setup to display a map of listings to users.
The jQuery.goMap.map code is used to load in the Google Maps instance used on the WordPress plugin.
I have wrote the following functions to store and load the latitude, longitude, and zoom level with local storage. The storing of the lat/lng and zoom levels is working, and the loading of the zoom level is working, but I cannot get the map to center on the loaded latitude and longitude position.
I have tried using bounds.extend(latLng); and jQuery.goMap.map.fitBounds(bounds); in the loadUserZoom function, but the result is a fully zoomed in map. This means the stored zoom level value is being ignored.
The current functioning code can be tested here.
The Clear text link in the header navigation can be used to clear the local storage values from the browser. This is implemented for testing purposes.
Any assistance is greatly appreciated.
Function: storeUserZoom
function storeUserZoom() {
let zoom = jQuery.goMap.map.getZoom();
localStorage.setItem( 'zoom', zoom);
let center = jQuery.goMap.map.getCenter();
let lat = center.lat();
let lng = center.lng();
let latLng = {
lat: lat,
lng: lng
}
localStorage.setItem( 'latLng', JSON.stringify(latLng));
}
Function: loadUserZoom
function loadUserZoom() {
if (localStorage.getItem( 'zoom' )) {
let zoom = parseInt(localStorage.getItem( 'zoom' ));
console.log(zoom);
// Logs correct zoom level
let latLng = JSON.parse(localStorage.getItem( 'latLng' ));
console.log(latLng);
// Logs Object { lat: 51.69124213478852, lng: -113.2478200914128 }
jQuery.goMap.map.setZoom(zoom);
jQuery.goMap.map.setCenter(latLng);
// latLng used is incorrect
}
}
I believe I have zeroed in on the problem by adjusting how the loadUserZoom function was executed in the initMap function.
The loadUserZoom function was wrapped in a Google Maps listen once event listener when the map was idle. The code is included below.
google.maps.event.addListenerOnce(jQuery.goMap.map, 'idle', function() {
loadUserZoom();
});
I had it set initially to addListener, which seemed to conflict with the required functionality. I assume this meant it was execute regularly whenever the map was in an idle state.
My updated loadUserZoom function is included below.
function loadUserZoom() {
if (localStorage.getItem( 'zoom' )) {
let zoom = parseInt(localStorage.getItem( 'zoom' ));
let latLng = JSON.parse(localStorage.getItem( 'latLng' ));
jQuery.goMap.map.setZoom(zoom);
jQuery.goMap.map.setCenter(latLng);
}
}

How to add MapQuest RouteLayer to leaflet layer

i want to implement in my leaflet app, feature that allows to find route between two selected points.To find route i want to use this library: mapquest
I have extended standard leaflet map class like this:
export class Map {
constructor(elementId, centerView, zoom ) {
this.layers = [];
this.map = this.init(elementId,centerView,zoom);
this.icons = {};
}
init(elementId, centerView, zoom) {
//console.log('Map::init('+elementId+', ['+centerView+'], '+zoom+')');
delete L.Icon.Default.prototype._getIconUrl;
const markerIcon = require('leaflet/dist/images/marker-icon.png');
const markerIcon2x = require('leaflet/dist/images/marker-icon-2x.png');
const markerShadow = require('leaflet/dist/images/marker-shadow.png');
L.Icon.Default.mergeOptions({
iconRetinaUrl: markerIcon2x.default,
iconUrl: markerIcon.default,
shadowUrl: markerShadow.default,
});
var map = L.map(elementId, {
center: [centerView[0], centerView[1]],
zoom: zoom
});
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(map);
return map;
}
}
And i wrote few functions that helps me to work with map(add point, markers etc).
This is how i'm initializing extended map object:
let centerView = [35.791188, -78.636755];
let zoom = 9;
var map = new Map('map', centerView, zoom);
And i found code how to generate route mapquest-routing.I'am taking coords by clicking on map which works fine. My function to generate route looks like this:
function runDirection(start, end)
{
var dir = MQ.routing.directions();
dir.route({
locations: [
start,
end
]
});
map.map.addLayer(MQ.routing.routeLayer({
directions: dir,
fitBounds: true
}));
}
But i'm getting error:
Uncaught Error: The provided object is not a Layer.
Which means MQ.routing.routeLayer(),doesnt return me leyer object.
So the question is, how can i add route to standard leaflet map?
You're using a deprecated library. On the https://developer.mapquest.com/documentation/leaflet-plugins/geocoding/ webpage there's a deprecation warning in big red letters, I quote:
We recommend using MapQuest.js instead.
The documentation in the webpage for that mapquest plugin for Leaflet lists compatibility for Leaflet 0.7.7 (which was published back on 2013). Leaflet uses semantic versioning, which means stuff that worked with 0.x has no guarantee of working with 1.x. It's safe to assume that the Leaflet plugin in question only works with Leaflet 0.7.x and older, and does not work with Leaflet 1.x.

Google Maps API -- Setting Icon for Marker Results in Error: "constructor Error cannot be invoked without 'new'"

I'm trying to create some markers to add using the Google Maps API, but if I try to specify an icon, I get the error: "constructor Error cannot be invoked without 'new'".
I'm running this via locahost.
Things I have tried:
Creating the marker, then setting the icon afterwards.
Different versions of the API.
Plugging my API key into the JSFiddle. (No errors.)
Removing/commenting out the icon lines. (Runs fine with the default icon.)
The code is pretty much verbatim from the Google-supplied JSFiddle for this, and it works there, but not on the page I'm working on.
const latlng = new google.maps.LatLng(this.location[0], this.location[1]);
this.marker = new google.maps.Marker({
position: latlng,
icon: {
path: google.maps.SymbolPath.CIRCLE,
scale: 10
},
draggable: false
});
I should have a circle icon at the specified position, but instead I get the following:
js?v=weekly&key=(APIKEY):53 Uncaught TypeError: Class constructor Error cannot be invoked without 'new'
at new Yc (:53)
at Object._.$c (:53)
at :56
at :56
at :56
at _.nf.setIcon (:66)
at .nf..T.setValues (:165)
at _.nf.mf [as constructor] (:79)
at new _.nf (:79)
at User.createMarker (classes.js:329)
It looks to me like there's a problem in the API's code that's making it difficult to debug the actual problem that's triggering the error.
Any suggestions would be appreciated.
Did you place the place in a class? I changed the official JSFiddle to use a class and it works.
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 4,
center: {
lat: -25.363882,
lng: 131.044922
}
});
var Location = class Location {
constructor(lat, lng) {
this.location = [lat, lng]
const latlng = new google.maps.LatLng(this.location[0], this.location[1]);
this.marker = new google.maps.Marker({
position: latlng,
icon: {
path: google.maps.SymbolPath.CIRCLE,
scale: 10
},
draggable: false
});
this.marker.setMap(map);
}
}
var location = new Location(-25.363882, 131.044922);
}
What's happening is that the API is calling on a global Error object within the setIcon chain of functions (despite, apparently, a total lack of errors), which was causing an error due to me having overridden it with a custom Error class I had naively tried to add to the project.
Info on Error:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error

JS OpenLayers get ol/Feature values on click

I am using OpenLayers and I want to get all values from Marker (ol.Feature).
You can see in docs it is possible to add any value to ol.Feature.
import Feature from 'ol/Feature';
import Polygon from 'ol/geom/Polygon';
import Point from 'ol/geom/Point';
var feature = new Feature({
geometry: new Polygon(polyCoords),
labelPoint: new Point(labelCoords),
name: 'My Polygon' // <--- CUSTOM VALUE
});
// get the polygon geometry
var poly = feature.getGeometry();
// Render the feature as a point using the coordinates from labelPoint
feature.setGeometryName('labelPoint');
// get the point geometry
var point = feature.getGeometry();
I have a click event on map and I want to get those values.
this.map.on('click', (args) => {
this.map.forEachFeatureAtPixel(args.pixel, (feature, layer) => {
// do something
console.log(feature.values_); // <---- SEEMS LIKE 'PRIVATE' prop
});
});
It looks like ol.Feature has no method for getting these values. Is there any 'nicer' solution than feature.values_ ?
You can get all properties using
feature.getProperties()
or if you just need one, you can do
feature.get('name')

How to store e.latlng into array : leaflet

I am working with leaflet api where user can put markers on map. I have made a custom button for putting marker.
I am willing to draw line between those markers i.e. using
L.polylines() but as I am new to javascript and leaflet I can't
understand how to pass those latlng point to array which will later be
used in these functions. For initial working I have passed static
coordinates(working as req).
L.easyButton('fa-link', function () {
var secureThisArea = [[-81, 100.75], [-76.50, 245.75], [-145.50, 184.25], [-128, 311.75]];
map.on('click', function fencePlace(e) {
L.marker([-81, 100.75], { icon: fenceIcon, draggable: true }).bindPopup("this is first").addTo(map);
L.marker([-76.50, 245.75], { icon: fenceIcon, draggable: true }).bindPopup("this is second").addTo(map);
L.marker([-145.50, 184.25], { icon: fenceIcon, draggable: true }).bindPopup("this is third").addTo(map);
L.marker([-128, 311.75], { icon: fenceIcon, draggable: true }).bindPopup("this is fourth").addTo(map);
L.polyline(secureThisArea).addTo(map);
});
}).addTo(map);
Adding another value to an array is easy, e.g.:
secureThisArea.push([-81, 100.75]);
You can find more details (also about anything else JavaScript related) at Mozilla Developer Network.
If you want to use the coordinates from the marker objects, you can get those with:
var myMarker = L.marker([-81, 100.75], { icon: fenceIcon, draggable: true }),
latLng = null;
latLng = myMarker.getLatLng();
Also take a look at the Leaflet documentation.
If i understand you correctly you want to create markers on click and connect them via polylines. That's easy to do, in code with comments to explain:
// Create new empty polyline and add it to the map
var polyline = new L.Polyline([]).addTo(map);
// Handle map click event
map.on('click', function(event) {
// New marker on coordinate, add it to the map
new L.Marker(event.latlng).addTo(map);
// Add coordinate to the polyline
polyline.addLatLng(event.latlng);
});
Now afterwards if you want to get all the coordinates added to the polyline you can use the getLatLngs method of L.Polyline which returns an array of L.LatLng objects.
Reference: http://leafletjs.com/reference.html#polyline
Example: http://plnkr.co/edit/h7aMwc?p=preview

Categories

Resources