Leaflet.Geosearch: get lon/lat from address - javascript

Without any knowledge of JS, I was forced to implement a map (OSM via Leaflet) on a webpage. On this map, there should be a marker for the actual address of a person. The address is saved as a string in the database.
I can see a map, can add marker to it, but after that, I'm lost.
I've tested some Leaflet-geocoding-plugins, but i must confess, that they're not simple enough for my actual programmming experience.
Another question was about the same problem, but i didn't understand, how to get the lon/lat from an address with the L.Geosearch-plugin for Leaflet.
Can anyone provide me a example of looking up an address (via OSMN or something else, not google/bing or other api-key-needy provider), converting it to lon/lat and add a marker to it on a map?

First you will have to include the .js files of a geocoder in the head of your HTML code, for my example I have used this one: https://github.com/perliedman/leaflet-control-geocoder. Like this:
<script src="Control.Geocoder.js"></script>
Then you will have to initialize the Geocoder in your .js:
geocoder = new L.Control.Geocoder.Nominatim();
Then you will have to specify the address that you are looking for, you can save it in a variable. For example:
var yourQuery = (Addres of person);
(You can also get the address out of your database, then save it in the variable)
Then you can use the following code to 'geocode' your address into latitude / longitude. This function will return the latitude / longitude of the address. You can save the latitude / longitude in an variable so you can use it later for your marker. Then you only have to add the marker to the map.
geocoder.geocode(yourQuery, function(results) {
latLng= new L.LatLng(results[0].center.lat, results[0].center.lng);
marker = new L.Marker (latLng);
map.addlayer(marker);
});

I made a jfsfiddle that
Has an address set
Looks for the coordinates of that address using geosearch
Creates a marker at the coordinates of that address found by geosearch.
It can be found here: https://jsfiddle.net/Alechan/L6s4nfwg/
The "tricky" part is dealing with the Javascript "Promise" instance returned by geosearch and that the address may be ambigous and more than one coordinate may be returned in that case. Also, be careful because the first position in the Leaflet coordinates corresponds to the latitude and the second to the longitude, which is in reverse of the Geosearch "x" and "y" results.
Geosearch returns a promise because it's an asynchronous call. The alternative would have to be a synchronous call and the browser would have to be freezed until an answer was retrieved. More info about promises from MDM (Mozilla) and Google.
In my example, I create a marker for every result found for the indicated address. However, in this case the address is unambiguous and returns only one result.
Breakdown of code:
<!-- Head, imports of Leaflet CSS and JS, Geosearch JS, etc -->
<div id='map'></div>
<script>
// Initialize map to specified coordinates
var map = L.map( 'map', {
center: [ 51.5, -0.1], // CAREFULL!!! The first position corresponds to the lat (y) and the second to the lon (x)
zoom: 12
});
// Add tiles (streets, etc)
L.tileLayer( 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap',
subdomains: ['a','b','c']
}).addTo( map );
var query_addr = "99 Southwark St, London SE1 0JF, UK";
// Get the provider, in this case the OpenStreetMap (OSM) provider.
const provider = new window.GeoSearch.OpenStreetMapProvider()
// Query for the address
var query_promise = provider.search({ query: query_addr});
// Wait until we have an answer on the Promise
query_promise.then( value => {
for(i=0;i < value.length; i++){
// Success!
var x_coor = value[i].x;
var y_coor = value[i].y;
var label = value[i].label;
// Create a marker for the found coordinates
var marker = L.marker([y_coor,x_coor]).addTo(map) // CAREFULL!!! The first position corresponds to the lat (y) and the second to the lon (x)
// Add a popup to said marker with the address found by geosearch (not the one from the user)
marker.bindPopup("<b>Found location</b><br>"+label).openPopup();
};
}, reason => {
console.log(reason); // Error!
} );
</script>

Related

Getting marker from map.data class use geojson google maps

first of all I was initiate marker from geojson, and how I can get the marker if i want use marker for listener/action?
this is my script
var map;
function initMap() {
//makes map
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: -6.9034482, lng: 107.6081381},
zoom: 9,
styles: [{"featureType":"water","stylers":[{"saturation":43},{"lightness":-11},{"hue":"#0088ff"}]},{"featureType":"road","elementType":"geometry.fill","stylers":[{"hue":"#ff0000"},{"saturation":-100},{"lightness":99}]},{"featureType":"road","elementType":"geometry.stroke","stylers":[{"color":"#808080"},{"lightness":54}]},{"featureType":"landscape.man_made","elementType":"geometry.fill","stylers":[{"color":"#ece2d9"}]},{"featureType":"poi.park","elementType":"geometry.fill","stylers":[{"color":"#ccdca1"}]},{"featureType":"road","elementType":"labels.text.fill","stylers":[{"color":"#767676"}]},{"featureType":"road","elementType":"labels.text.stroke","stylers":[{"color":"#ffffff"}]},{"featureType":"poi","stylers":[{"visibility":"off"}]},{"featureType":"landscape.natural","elementType":"geometry.fill","stylers":[{"visibility":"on"},{"color":"#b8cb93"}]},{"featureType":"poi.park","stylers":[{"visibility":"on"}]},{"featureType":"poi.sports_complex","stylers":[{"visibility":"on"}]},{"featureType":"poi.medical","stylers":[{"visibility":"on"}]},{"featureType":"poi.business","stylers":[{"visibility":"simplified"}]}]
});
//load marker from geojson
map.data.loadGeoJson('<?php echo base_url().'index.php/json_site/geojsongetmap'?>');
// set style marker
map.data.setStyle(function(feature){
var tit = feature.getProperty('nm_site');
return{
title: tit,
icon: '<?php echo base_url()?>assets/images/mark3.png'
};
});
//marker event
map.data.addListener(marker, 'click', function(event) {
map.setZoom(11);
map.setCenter(marker.getPosition()); // I need to get the position of the marker who i clicked
});
}
how I can make action listener if I initiate marker from geojson?
and how I can get the marker who existing in my map?
please help me, any suggest would be appreciated
thanks
Instances of the google.maps.Data.Point class are not exactly a drop-in replacement for traditional google.maps.Marker objects. For starters, they are abstract data, not tied to a particular representation. It's up to the parent google.maps.Data layer to decide how to draw them.
However, you can still capture events, with the caveat that the click happens on the Data layer, which receives a mouseEvent as argument. This argument contains the feature over which you just clicked.
This means you need to declare:
google.maps.event.addListener(map.data,'click',function(mouseEvent) {
var clickedFeature = mouseEvent.feature,
featureGeometry = clickedFeature.getGeometry(),
featurePosition = featureGeometry.get();
map.setCenter(featurePosition);
});
Please take into consideration that ingesting geoJson with the Data layer can result not just in Point geometries. If you get a mix of points, polygons and linestrings, anything different from a point won't return a latLng object when you call its get method.

Google Earth API search by Placemarker Name

I am trying to create search box for Google Earth API Plugin for javascript
I am able to parse KMLFile and load in GE API and now I have to embed search by Placemarker name loaded by KML
Code using Lat & Long
var lookAt = ge.createLookAt('');
lookAt.set(point.y, point.x, 600, ge.ALTITUDE_RELATIVE_TO_GROUND, 0, 00, 0);
ge.getView().setAbstractView(lookAt);
Is there any possiblity for LookAt using Placemarker Name except using LAT, LONG?
Yes, there are lots of ways to look at placemarks. The easiest way to do this is if the placemark has and abstract view defined. e.g.
if (placemark.getAbstractView()) {
ge.getView().setAbstractView(placemark.getAbstractView());
}
You can also use the various accessors to refer to a placemark. For example if the placemark has an ID you can use getElementById.
var placemark = ge.getElementById('MyPlacemark');
if (placemark.getAbstractView()) {
ge.getView().setAbstractView(placemark.getAbstractView());
}
Or else if you are loading KML by its URL, e.g.
// loaded via KML
var placemark = ge.getElementByUrl('http://site.com/foo.kml#MyPlacemark');
if (placemark.getAbstractView()) {
ge.getView().setAbstractView(placemark.getAbstractView());
}
If the placemark doesn't have an abstract view you can still use the accessors to find the correct placemark and then extract the geometry from it to create the look at.
var placemark = ge.getElementByUrl('http://site.com/foo.kml#MyPlacemark');
var point = placemark.getGeometry();
var lat = point.getLatitude();
var lng = point.getLongitude();

Display markers on Google Map using JSON

I have the following test Google Map: http://dev.driz.co.uk/googlemap/
I'm using the design of Foursquare markers as an example to test out my code and so far I have implemented a simple display of where YOU the user is in the world with a small avatar and when you hover it tells you this in the form of a tooltip.
The next part is using some JSON data: http://dev.driz.co.uk/googlemap/data.json
I want to display those 5 posts on the map using the coordinates that are stored in the data and display them in a similar fashion to the current marker. The user will then hover the marker and be able to see a tooltip with the following information as an example:
Cameron asked:
Is Star Wars 3d still on at the cinema?
2012-05-20 02:31:21
The user should be able to click on the marker to be taken to the post.
I've had a look around the Developer section of Google Maps, but don't seem to getting the right stuff and not sure how best to use it with my tooltip function and map implementation.
Can anyone help? Post some code examples?
Thanks
Follow these steps
Pull the data using an AJAX request and store it in a variable.
You can use jQuery for this. http://api.jquery.com/jQuery.getJSON/
$.getJSON('http://dev.driz.co.uk/googlemap/data.json', function(data){
// loop and add markers
});
Or you can use plain javascript and a JSON parser.
http://www.degraeve.com/reference/simple-ajax-example.php
http://www.json.org/
Loop in data and pick each item and add to map
for (var i = 0; i < data.length; i++) {
var item = data[i];
var markerLatlng = new google.maps.LatLng(item.Post.latitude, item.Post.longitude);
var marker = new google.maps.Marker({
position: markerLatlng
});
marker.item = item; // store information of each item in marker
marker.setMap(map); // where `map` is the instance of Google Map
google.maps.event.addListener(marker, "click", function(mark) {
// retrieve information using `this.item` and create dynamic HTML to show it.
// this.item.Post.datetime, this.item.Post.content etc.
});
}

Adding Geolocation to Google Places Library

We're trying to build an app that allows users to view places around their current location.
You can see the Google Maps API & the Google Places Library functioning here, but not as one: http://www.blazingsasquatch.com/geo/index4.html
You'll notice the button "show me my loc" pulls your current location and the map is showing an arbitrary location in Boston with places nearby.
We've created variables for both the longitude and latitude and we've attempted to pass those variables directly into the "pyrmont" location variable but we've had no luck.
Initially we tried setting the "pyrmont" location using following, also with no luck:
google.maps.LatLng(position.coords.latitude, position.coords.longitude);
So how can we get the current location populated?
var pyrmont = new google.maps.LatLng("CURRENT LOCATION HERE");
Will it accept a variable or an integer only?
initialize will be called before the callback of navigator.geolocation.getCurrentPosition() , so you cannot use the result in initialize() .(you may view getCurrentPosition as a asynchronous request)
Invoke the action(creation of the marker and places-request) inside the callback of getCurrentPosition()
See a working demo: http://jsfiddle.net/doktormolle/C5ZtK/
The LatLng constructor takes two floating point numbers, like so:
pos = new google.maps.LatLng(-34.397, 150.644);
After reviewing the source code, it seems the problem is another one: the anonymous callback function you are passing to getCurrentPosition() is called when the geographic location is found, which can take some time (especially using GPS and such). initialize() is called when the page is loaded, which is sooner, so place is not set at this time (besides, it's not visible in initialize() since it's not a global variable, but never mind that). So you have to move the stuff you're currently doing in initialize() to the callback function you are passing to getCurrentPosition(). Then, you can use
var pyrmont = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);

Google Maps V3: Only show markers in viewport - Clear markers issue

I like to create a map with Google Maps that can handle large amounts of markers (over 10.000). To not slow down the map I've created a XML-file that only outputs the markers that are inside the current viewport.
First, I use initialize() to setup the map options:
function initialize() {
var myLatlng = new google.maps.LatLng(51.25503952021694,3.27392578125);
var myOptions = {
zoom: 8,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
google.maps.event.addListener(map, 'tilesloaded', function () {
loadMapFromCurrentBounds(map);
});
}
When the event 'tilesloaded' is finished, I use loadMapFromCurrentBounds(), this functions will get the current bounds and sends a request to the XML-file to show the markers that are inside the current viewport:
function loadMapFromCurrentBounds(map) {
// First, determine the map bounds
var bounds = map.getBounds();
// Then the points
var swPoint = bounds.getSouthWest();
var nePoint = bounds.getNorthEast();
// Now, each individual coordinate
var swLat = swPoint.lat();
var swLng = swPoint.lng();
var neLat = nePoint.lat();
var neLng = nePoint.lng();
downloadUrl("mapsxml.php?swLat="+swLat+"&swLng="+swLng+"&neLat="+neLat+"&neLng="+neLng+"", function(data) {
var xml = parseXml(data);
var markers = xml.documentElement.getElementsByTagName("marker");
var infoWindow = new google.maps.InfoWindow;
for (var i = 0; i < markers.length; i++) {
var address = markers[i].getAttribute("address");
var type = markers[i].getAttribute("type");
var name = markers[i].getAttribute("name");
var point = new google.maps.LatLng(
parseFloat(markers[i].getAttribute("lat")),
parseFloat(markers[i].getAttribute("lng"))
);
var html = "<b>" + name + "</b> <br/>" + address;
var icon = customIcons[type] || {};
var marker = new google.maps.Marker({
map: map,
position: point,
icon: icon.icon,
shadow: icon.shadow});
bindInfoWindow(marker, map, infoWindow, html);
}
})
}
This is working great, however, the current code doesn't offload markers that aren't in de viewport anymore. Besides that, it loads markers again who are already loaded, that slows down the map really fast when moving the map a view times in the same area.
So when the viewport changes, I like to clear the whole map first before loading new markers. What is the best way to do this?
You need to add another Event Listener to the map:
google.maps.event.addListener(map,'bounds_changed', removeMarkers);
See here for more on removing all markers from a google map - unfortunately I dont think it can be done with one call. So you will have to write the removeMarkers or something similar which will have to iterate through all the markers on the map removing them individually like so:
markersArray[i].setMap(null);
I don't know whether it's quicker to check if the marker is in the viewport before removing by using:
map.getBounds();
Read more about Google Map API v3 events
Due to the following explanation using 'tilesloaded' or 'bounds_changed' would be very wrong and cause unwilling continuous firings. Instead you would want to use 'idle' event which will fire once the user has stopped panning/zooming.
google.maps.event.addListener(map, 'idle', loadMapFromCurrentBounds);
https://developers.google.com/maps/articles/toomanymarkers#viewportmarkermanagement
You may want to check out this thread. Daniel answered this quite nicely.
What's the most efficient way to create routes on google maps from gps files?
Also, bounds_changed is the first opportunity to call your function. tilesloaded, will be called constantly. The viewport may contain more than one tile to fill the viewport.
Alternatively, you can also do a setVisible(false).
In order to remove the marker, you may need to remove the listeners.
google.maps.event.clearInstanceListeners(marker);
marker.setMap(null);
markers.remove(marker);
delete marker;
This article goes through it pretty nicely:
Dynamically loading thousands of markers in Google Maps
dynamically load markers until we reach a threshold
keep a hashtable of markers that have already been added
after the threshold has been reached, remove markers that aren’t currently within the viewport
remove all markers from the map when the user has zoomed out, and don’t load any markers until the user zooms back to a reasonable level
Your original function seems like a lot of code. I'd do something like this:
if( map.getBounds().contains(markers[i].getPosition()) ) {
myMarkerDisplayFunction(markers[i]);
}
You might want to check out this documentation from Google. It explains what you need:
With the new list of markers you can remove the current markers
(marker.setMap(null)) that are on the map and
add the new ones (marker.setMap(map)).

Categories