I am trying to build a map app that use address name in data base and display marker in leaflet map. I had come across leaflet esri plugin but not sure how to use the code. Could anyone please teach me how to extract result(longitude and latitude) from the geocoding function and draw a marker? Thanks!
Geocode function:
L.esri.Geocoding.geocode(<Object> options)
Results:
{results: [
{
latlng: L.LatLng,
text: 'Formatted Address',
score: 100, // certainty ranking of the match
properties: {
// additional info like specific address components (Country Code etc.)
}
}
]
}
http://esri.github.io/esri-leaflet/api-reference/tasks/geocode.html
Here is an example using ES6:
import L from "leaflet";
// import library as ELG
import * as ELG from "esri-leaflet-geocoder";
// here is an example address in the US - use the one from your DB
const address = "380 New York St, Redlands, California, 92373";
// call geocode method of the library, no need to call L.esri.Geocoding.geocode() as in vanilla js
ELG.geocode()
// pass the address
.text(address)
.run((err, results, response) => {
console.log(results.results[0].latlng);
// retrieve latitude, longitude from related response
const { lat, lng } = results.results[0].latlng;
// build a marker using the retrieved address
L.marker([lat, lng])
.addTo(mymap)
.bindPopup(address)
.openPopup();
});
Demo
Related
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);
}
}
This question already has an answer here:
Reverse Geocoder Returning undefined
(1 answer)
Closed 1 year ago.
I am a newbie in web development. Today, I am trying to use Google Map API to get the country name and the state name from longitude and latitude using JavaScript. I read the documentation from the Google Map API and did some research but I was kinda confused about this. I gave it a go and this is what I did:
function getCountryName(latitude, longitude){
var country;
const geocoder = new google.maps.Geocoder();
geocoder.geocode({location: {lat: latitude, lng: longitude}}, (results, status) => {
if(status === "OK"){
if(results[0]){
country = results[0].address_components[0].types[0].country;
}
else{
country = "N/A";
}
}
});
return country;
}
However, I keep getting the "undefine" result. Is there anything wrong with my approach?
Thanks you all in advance!
You seem to be confused about the asynchronous programming happening here.
Basically you have return country; statement at the end of function execution which will always be undefined since the results haven't been fetched by that time.
The 2nd parameter that you are sending to the geocoder.geocode is a callback function that will be called once google has fetched the results which obviously takes a little bit of time.
So your function should be something like this
function getCountryName(latitude, longitude, onSucess){
const geocoder = new google.maps.Geocoder();
geocoder.geocode({location: {lat: latitude, lng: longitude}}, (results, status) => {
if(status === "OK"){
if(results[0]){
onSucess(results[0].address_components[0].types[0].country);
}
else{
onSucess("N/A");
}
}
});
return country;
}
And when you are about to use this function elsewhere, you have to use it like this
getCountryName(1.1111, 2.2222, (country) => {
alert(country);
console.log(country);
// You can do anything here like showing it to ui or using it elsewhere
}
If you want to learn more about callbacks in JS, go through this Article.
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.
I am using the Leaflet plugin leaflet-control-geocoder found here: https://github.com/perliedman/leaflet-control-geocoder
My aim is to restrict the results by country = UK and city = london.
My current code which works fine but am getting results also from outside UK
var geocoder = L.Control.geocoder({position:'topleft', geocode:'countrycodes=gb'});
geocode.addTo(map);
The geocode uses Nominatim to respond to geocoding queries. Not sure why its not working
The way i have restrict country
var options = {
position: 'topright',
geocoder: new L.Control.Geocoder.nominatim({
geocodingQueryParams: {
"countrycodes": "gb"
}
})
};
var geocoder = L.Control.geocoder(options).addTo(map);
I believe that you need to write L.Control.Geocoder.nominatim({position:'topleft', geocode:'countrycodes=gb'}) to specify that you're using Nominatim.
That is what they do in the demo at this link: https://github.com/perliedman/leaflet-control-geocoder/blob/master/demo/index.html
If you use geocoder without nominatim(), then you can do the country filter as the following. The loops are ugly I know, it could be better solved with mapping to object. It's just for demonstration.
geocoder.query('pass-a-search-string-criteria', showResult);
function showResult(err, data) {
if (!map) {
map = L.mapbox.map('your-map-id', 'mapbox.streets');
}
if (data.lbounds) {
[].slice.call(data.results.features).forEach(function(place){
[].slice.call(place.context).some(function(ccode, i) {
if (i === 3 && ccode.short_code ==='gb') {
console.log(place.place_name);
}
});
});
map.fitBounds(data.lbounds);
} else if (data.latlng) {
map.setView([data.latlng[0], data.latlng[1]], 13);
}
}
I'm developing with Nokia Maps (a wonderful option I really love them) but I'm only able to get the location (latitude and longitude) with HTML5 but I can't the name where I am :/, maybe somebody could give an idea, how to do it, thank you very mach for your help.
Maps API for JavaScript 3.x
The current 3.x JavaScript API offers a thin wrapper around the REST Geocoder API. You need to make a ReverseGeocode search, and then extract the data from the Location object(s) found in the result.
A fully working reverse geocoding example can be found here, but the important bit (getting the address) can be see below:
function reverseGeocode(platform) {
var geocoder = platform.getGeocodingService(),
reverseGeocodingParameters = {
prox: '52.5309,13.3847,150', // Location
mode: 'retrieveAddresses',
maxresults: '1',
jsonattributes : 1
};
geocoder.reverseGeocode(
reverseGeocodingParameters,
function (result) {
var locations = result.response.view[0].result;
// ... etc.
},
function (error) {
alert('Ooops!');
}
);
}
Maps API for JavaScript 2.x (deprecated)
With the recently deprecated 2.x JavaScript API, again you need to make a ReverseGeocode search, and then extract the data from the Address object found in the result.
The code is a bit longer, but the important bit (getting the address) can be seen below:
// Function for receiving search results from places search and process them
var processResults = function (data, requestStatus, requestId) {
var i, len, locations, marker;
if (requestStatus == "OK") {
// The function findPlaces() and reverseGeoCode() of return results in slightly different formats
locations = data.results ? data.results.items : [data.location];
// We check that at least one location has been found
if (locations.length > 0) {
for (i = 0, len = locations.length; i < len; i++) {
alert(locations[i].address.street);
alert(locations[i].address.state);
}
} else {
alert("Your search produced no results!");
}
} else {
alert("The search request failed");
}
};
/* We perform a reverse geocode search request: translating a given
* latitude & longitude into an address
*/
var reverseGeoCodeTerm = new nokia.maps.geo.Coordinate(
52.53099,
13.38455
);
nokia.places.search.manager.reverseGeoCode({
latitude: reverseGeoCodeTerm.latitude,
longitude: reverseGeoCodeTerm.longitude,
onComplete: processResults
});