I need to recalculate the directions, when another marker is clicked or when my origin marker is dragged to another location.
at the moment, I am inserting a marker when a user inserts his/her address then when the users clicks on any existing marker it calculates the directions. Unfortunately it doesn't clear the previous directions.
Any Help at all will be greatly appreciated.
Here's the code:
jQuery(document).ready(function() {
jQuery.getJSON('./index.php', {
option: "com_locate",
view: "branches",
tmpl: "component",
format: "json",
},
function(json){
jQuery(function(){
jQuery("#googleMap").gmap3({
map:{
options: {
center:[-29.8191,25.3499],
zoom: 5,
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl: false,
streetViewControl: false
}
},
marker: {
values: json,
options: {
icon: new google.maps.MarkerImage("http://maps.gstatic.com/mapfiles/icon_green.png")
},
events:{
mouseover: function(marker, event, context){
jQuery(this).gmap3(
{clear:"overlay"},
{
overlay:{
id: "tooltip",
latLng: marker.getPosition(),
options:{
content: "<div class='infobulle"+(context.data.drive ? " drive" : "")+"'>" +
"<div class='bg'></div>" +
"<div class='text'>" + context.data.city + " (" + context.data.telephone + ")</div>" +
"</div>" +
"<div class='arrow'></div>",
offset: {
x:-46,
y:-73
}
}
}
});
},
mouseout: function(){
jQuery(this).gmap3({clear:"overlay"});
},
click: function(marker, event, context){
markerSelected(context.id);
}
}
}
});
///////////////
jQuery('#test-ok').click(function(){
var addr = jQuery('#test-address').val();
if ( !addr || !addr.length ) return;
jQuery("#googleMap").gmap3({
getlatlng:{
address: addr,
callback: function(results){
if ( !results ) return;
jQuery("#googleMap").gmap3({
clear:{id:"user"}
},
{
marker:{
latLng:results[0].geometry.location,
id:"user",
name:"user",
options:{
draggable: true
}
},
map:{
center: true,
zoom: 5
}
});
}
}
});
});
jQuery('#test-address').keypress(function(e){
if (e.keyCode == 13){
jQuery('#test-ok').click();
}
});
///////////////
///////////////
function markerSelected(id){
var marker = jQuery('#googleMap').gmap3({get:id});
var usermarker = jQuery('#googleMap').gmap3({get:"user"});
jQuery("#googleMap").gmap3({
getroute:{
options:{
origin:[usermarker.getPosition().lat(),usermarker.getPosition().lng()],
destination:[marker.getPosition().lat(),marker.getPosition().lng()],
travelMode: google.maps.DirectionsTravelMode.DRIVING
},
callback: function(results){
if (!results) return;
jQuery(this).gmap3({
map:{
options:{
}
},
directionsrenderer:{
container: jQuery(document.createElement("div")).addClass("googlemap").insertAfter(jQuery("#googleMap")),
options:{
directions:results
}
}
});
}
}
});
}
});
});
});
The code you're using creates a new DOM element each time you do a directions request, without removing any existing such elements or replacing content in any existing elements. The pertinent part of your code is this:
directionsrenderer:{
container: jQuery(document.createElement("div")).addClass("googlemap").insertAfter(jQuery("#googleMap")),
// The above creates a new DOM element every time markerSelected() is called!
options:{
directions:results
}
}
You want to create that only once. If you want, you can do it directly in the HTML markup.
Use the below as a replacement for your getroute callback function. I've plugged in a unique ID for the container element and left the "googlemap" class intact in case it's needed for CSS or other sections of code. Since you specifically want only one set of directions to be visible, though, let's select your container by ID.
callback: function(results){
if (!results) return;
if (!jQuery("#dircontainer").length>0) {
jQuery("<div id='dircontainer' class='googlemap'></div>").insertAfter("#googleMap");
} // Creates your directions container if it doesn't already exist.
else {
jQuery("#dircontainer").html("");
} /* I'm clearing the existing contents of the container in case gmap3 doesn't
automatically clear it when the new directions are inserted.
You can experiment with removing this else statement. */
jQuery(this).gmap3({
map:{
options:{
}
},
directionsrenderer:{
container: jQuery("#dircontainer"),
options:{
directions:results
}
}
});
}
I'm making some assumptions here about the way the gmap3 plugin works; I've worked with jQuery and the Google Maps JS API, but not with this plugin.
Related
I am building a widget that will create a map based on Google Maps API. I am having a hard time to use the context of the widget inside the event listener.
Here is my code:
(function( $ ) {$.widget( "al.Mappable", {
options: {
lat: null,
lng: null,
bounds: null,
verbose: true,
showMap: true,
googleMap: {
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
},
googleMap: null,
self: null,
_create: function() {
this.debug("create widget");
self: this,
this._setupMap = $.proxy(this._setupMap, this);
if (this.options.showMap){
this._setupMap();
}
},
_setupMap: function(){
this.debug("init map");
// debugger;
if(this.options.lat && this.options.lng){
this.options.googleMap.center = this._latLng(this.options);
}
else{
//kaboom address
this.options.lat = 38.945596;
this.options.lng = -77.064773;
this.options.googleMap.center = this._latLng(this.options);
}
this.googleMap = new google.maps.Map(this.element[0], this.options.googleMap);
this._addUserLocation(38.945596,-77.064773);
google.maps.event.addListenerOnce(this.googleMap, 'tilesloaded',this._refreshMap(this.googleMap) );
},
_refreshMap: function(gmap){
bounds = gmap.getBounds()
this.options.bounds = bounds
dataOptions ={
searching: true,
keyword: getParam('keyword'),
playspace_type: getParam('playspace_type'),
location_type: getParam('location_type'),
bounds: bounds.toUrlValue()
}
// note the 'dummy event' in the callback since ujs sends the event as the first argument
// $.ajax "/playspaces/search.js",
// context: this
// data: dataOptions
// dataType: 'json'
// success: (data,status,xhr) -> #afterResultsAjax('dummyevent',data,status,xhr, false)
},
_latLng: function(opt){
return new google.maps.LatLng(opt.lat,opt.lng);
},
});
}( jQuery ));
When i do ("#map").mappable(), i am getting and error because bounds are undefined and toUrlValue() is throwing an error. the explianation is that bounds = gmap.getBounds() is triggered before that the event tileloaded is triggered.
I have tried to do this:
google.maps.event.addListenerOnce(this.googleMap, 'tilesloaded', function(){
console.log(this);
});
and i am getting the googleMap object back instead of the widget object. I have tried:
google.maps.event.addListenerOnce(this.googleMap, 'tilesloaded', function(){
console.log(self);
});
and i am getting the window object.
Question:
How can i get the context of the widget in the eventListener callback function? Is there another way to wait for the map to load and then refresh it with the markers?
I have been trying to use google map with angularJS.
I have learned how to use it through https://angular-ui.github.io/angular-google-maps/#!/.
Everything goes well.
For each marker, I can show InfoWindow which has an element information of myList.
But I have got stuck in InfoWindow with cluster.
When cluster is clicked, I want to show the information list of markers in cluster.
Even I can't show simple InforWindow when clicking the cluster.
Below sources are my code.
Please tell me if it is not enough to solve my problem.
Please tell me what is wrong and how to solve this.
Have a nice day.
* javascript
$scope.map.map = {
center: { latitude: $scope.map.myList[0].lat, longitude: $scope.map.myList[0].lng },
zoom: 17,
events : {
tilesloaded: function (map) {
$scope.$apply(function () {
google.maps.event.addDomListener(window, 'resize', function() {
var lat = $scope.map.myList[$scope.map.markerPosition-1].lat;
var lng = $scope.map.myList[$scope.map.markerPosition-1].lng;
var center = new google.maps.LatLng(lat, lng);
map.setCenter(center);
});
});
}
},
markersEvents: {
click: function(marker, eventName, model) {
model.show = !model.show;
return;
}
},
clusterOptions : { // options of cluster
gridSize: 40,
ignoreHidden: true,
zoomOnClick : false,
averageCenter : true,
styles: [
{
height: 53,
url: "http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/images/m3.png",
width: 53,
textColor : 'white'
}
]
},
clusterEvent: { // when cluster's clicked
click: function(map, markers) {
var contentString = 'ABCD';
var infowindow = new google.maps.InfoWindow({
content: contentString
});
infowindow.open(map, markers);
return;
}
}
};
$scope.map.options = {
streetViewControl : false
};
$scope.map.markers = [];
* html
<ui-gmap-google-map center='map.map.center' zoom="map.map.zoom" options="map.options" events="map.map.events">
<ui-gmap-markers models="map.markers" coords="'self'" icon="a" events="map.map.markersEvents" options="'options'"
doCluster="true" clusterOptions="map.map.clusterOptions" clusterEvents="map.map.clusterEvent">
<ui-gmap-windows show="show">
<div ng-non-bindable>{{id}}</div>
</ui-gmap-windows>
</ui-gmap-markers>
Answer myself.
var infoWindowOptions = {
content: "asdfasdf"
};
var infowindow = new google.maps.InfoWindow(infoWindowOptions);
infowindow.open(map.map_, *marker*);
I'm trying to make a Polymer module for working with OpenLayers 3 and displaying openstreetmaps. I know there is a great module working with leaflet but I need some specifics functions like map orientation.
Anyway, I code something and it's working except one thing I can't figure out : When the page loads, only the commands are showing (Zoom + / Zoom -) and not the map (and not any thing such as marker, etc). But if I resize my window (my Chrome window I mean) the map appear and all is working fine !! I was thinking maybe something in relation with DOM Loading...
Module code :
<dom-module id="openlayer-map">
<link rel="stylesheet" href="http://openlayers.org/en/v3.7.0/css/ol.css" type="text/css">
<script src="http://openlayers.org/en/v3.7.0/build/ol.js" type="text/javascript"></script>
<style>
:host {
display: block;
}
#map
{
position: absolute;
height: 100%;
}
</style>
<template>
<div id="map" class="map"></div>
<!-- Tests
<input is="iron-input" bind-value="{{latitude}}" placeholder="latitude">
<input is="iron-input" bind-value="{{longitude}}" placeholder="longitude">
-->
</template>
</dom-module>
<script>
(function() {
Polymer({
is: 'openlayer-map',
properties:
{
currentCenter: Array,
currentView: ol.View,
olmap: ol.Map,
geolocation: ol.Geolocation,
layer: Object,
longitude:
{
type: Number,
value:12.889101100000062,
notify: true,
observer: '_updateLongitude'
},
latitude:
{
type: Number,
value: 15.7622695,
notify: true,
observer: '_updateLatitude'
},
geotracking:
{
value: false,
type: Boolean,
notify: true,
},
elemReady: Boolean,
},
ready: function()
{
console.log('openlayer-map ready');
this.initialConfig();
this.elemReady = true;
this.setCenter(this.latitude,this.longitude);
},
initialConfig: function()
{
console.log('initial config for the map...');
this.currentView = new ol.View({
zoom: 14
});
var source = new ol.source.OSM();
this.layer = new ol.layer.Tile();
this.layer.setSource(source);
this.olmap = new ol.Map({
layers: [this.layer],
target: this.$.map,
controls: ol.control.defaults({
attributionOptions: /** #type {olx.control.AttributionOptions} */ ({
collapsible: false
})
}),
view: this.currentView
});
// Localisation
this.geolocation = new ol.Geolocation({
projection: this.currentView.getProjection()
});
this.geolocation.setTracking(this.geotracking);
if(this.geolocation)
{
var accuracyFeature = new ol.Feature();
this.geolocation.on('change:accuracyGeometry', function() {
accuracyFeature.setGeometry(this.geolocation.getAccuracyGeometry());
}.bind(this));
var positionFeature = new ol.Feature();
positionFeature.setStyle(new ol.style.Style({
image: new ol.style.Circle({
radius: 6,
fill: new ol.style.Fill({
color: '#3399CC'
}),
stroke: new ol.style.Stroke({
color: '#fff',
width: 2
})
})
}));
this.geolocation.on('change:position', function() {
var coordinates = this.geolocation.getPosition();
positionFeature.setGeometry(coordinates ?
new ol.geom.Point(coordinates) : null);
}.bind(this));
var featuresOverlay = new ol.layer.Vector({
map: this.olmap,
source: new ol.source.Vector({
features: [accuracyFeature, positionFeature]
})
});
}
},
_updateLatitude: function(newValue, oldValue)
{
if(this.elemReady)
{
console.log('update latitude from '+oldValue+' to '+newValue);
this.setCenter(newValue, this.longitude);
}
else
{
console.log('_updateLatitude: waiting element to be ready');
}
},
_updateLongitude: function(newValue, oldValue)
{
if(this.elemReady)
{
console.log('update longitude from '+oldValue+' to '+newValue);
this.setCenter(this.latitude, newValue);
}
else
{
console.log('_updateLatitude: waiting element to be ready');
}
},
setCenter: function(latitude, longitude)
{
var center = [longitude, latitude];
this.currentCenter = ol.proj.fromLonLat(center);
console.log('update center of the map with latitude = '+latitude+' and longitude = '+longitude);
this.currentView.centerOn(this.currentCenter,[400,400], [0,0]);
},
});
})();
</script>
And the call in Polymer :
<openlayer-map latitude="48.853" longitude="2.35" geotracking></openlayer-map>
Any clue ?
Found it ! Needed to do the map initialization in an asynchronous call
attached: function()
{
this.async(function()
{
this.initialConfig(); // Create your ol.Map here
});
},
I have this code that allows the user to enter two cities, and shows the location of the given inputs. But what I want is to show as well the direction from the 1st city to the other. How to do that?
Here is my practice code:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<style type="text/css">
html { height: 100% }
body { height: 100%; margin: 0; padding: 0 }
#map_canvas { height: 100% }
</style>
<script type="text/javascript"
src="http://maps.googleapis.com/maps/api/js?key=AIzaSyBQ8OCC8En5vNHod25Ov3Qs5E1v7NPRSsg&sensor=true">
</script>
<script type="text/javascript">
var geocoder;
var map;
function initialize1() {
var mapOptions = {
center: new google.maps.LatLng(-34.397, 100.644),
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map_canvas"),
mapOptions);
}
function initialize() {
// add mapOptions here to the values in the input boxes.
var mapOptions = {
center: new google.maps.LatLng(-34.397, 100.644),
zoom: 12,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map_canvas"),mapOptions);
geocoder = new google.maps.Geocoder();
addAddress(document.getElementById('from').value);
addAddress(document.getElementById('to').value);
}
function addAddress(place) {
var address = place;
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
}
</script>
</head>
<body>
From: <input id="from" type="text" name="From"><br>
To: <input id="to" type="text" name="To"><br>
<button type="button" onclick="initialize()">View example (map-simple.html)</button>
<div id="map_canvas" style="width:100%; height:100%"></div>
</body>
</html>
thanks
Jason
Use the DirectionsService in the Google Maps API v3. Here is an example from the documentation:
https://google-developers.appspot.com/maps/documentation/javascript/examples/directions-simple
and with text directions:
https://google-developers.appspot.com/maps/documentation/javascript/examples/directions-panel
if you mean the "location" means the address you can use the direction renderer like below to get the direction.
First of all store the location address of the two markers into the two text boxes if you want to display the to and from address with id's #from and #destination then follow the below code
$("#find").click(function () {
starting = $("#from").val();
finishing = $("#destination").val();
$("#map").gmap3(
{
action: 'getRoute',
options: {
origin: starting,
destination: finishing,
travelMode: google.maps.DirectionsTravelMode.DRIVING
},
callback: function (results) {
if (!results) {
alert("returning")
return
};
$(this).gmap3(
{
action: 'addDirectionsRenderer',
options: {
preserveViewport: true,
draggable: false,
directions: results
}
}
);
}
})
})
Explanation : At first I created two markers of different locations and different data then after the dragend of any marker there will be infowindow that shows the address and two buttons start and finish. I think you have done upto this part .
So after this I used two text boxes which will be filled according to the start button or finish button clicked .
After this if the user clicks the find button this text boxes values are used to find the direction between the two markers
Note: "here you can any marker for from or to only difference you have to maintain is to change the button clicked that is start or finish ....."
"You can even directly give the address in the text boxes and find the directions between them"
Here for whole manipulation I used gmap3 here is the code below that might help you
<script type="text/javascript">
window.onload = clear;
function clear() {
$("#from").val(null)
$("#destination").val(null)
}
$(document).ready(function () {
var starting = "";
var finishing = "";
$("#find").click(function () {
starting = $("#from").val();
finishing = $("#destination").val();
$("#map").gmap3(
{
action: 'getRoute',
options: {
origin: starting,
destination: finishing,
travelMode: google.maps.DirectionsTravelMode.DRIVING
},
callback: function (results) {
if (!results) {
alert("returning")
return
};
$(this).gmap3(
{
action: 'addDirectionsRenderer',
options: {
preserveViewport: true,
draggable: false,
directions: results
}
}
);
}
})
})
$("#map").gmap3({
action: 'addMarkers',
markers: [ //markers array
{lat: 22.74, lng: 83.28, data: 'madhu' },
{ lat: 17.74, lng: 82.28, data: 'raghu' }
],
map: { // this is for map options not for any markers
center: [17.74, 83.28],
zoom: 5
},
marker: {
options: {
draggable: true
},
events: {// marker events
dragend: function (marker, event, data) {
var contentString = '<div id="main content">'
+ '<input type="button" id="start" value="start" />'
+ '<input type="button" id="finish" value="finish" />'
+ '</div>';
//get address on click event
$(this).gmap3({
action: 'getAddress',
latLng: marker.getPosition(),
callback: function (results) {
var map = $(this).gmap3('get'),
infowindow = $(this).gmap3({ action: 'get', name: 'infowindow' })
if (infowindow) {
content = results && results[1] ? results && results[1].formatted_address : 'no address';
infowindow.open(map, marker);
infowindow.setContent(content + contentString);
}
else {
content = results && results[1] ? results && results[1].formatted_address : 'no address';
$(this).gmap3({
action: 'addinfowindow',
anchor: marker,
options: { content: content + contentString },
events: {
domready: function () {
$("#start").click(function () {
alert("start clicked " + content);
$("#from").val(content);
starting = content;
check();
})
$("#finish").click(function () {
alert("finish clicked " + content);
$("#destination").val(content);
finishing = content;
})
}
}
});
}
}
});
},
}
},
});
});
</script>
here is the html part for the above
<div id="headinput">
<input type="text" value="enter from" id="from" />
<input type="text" value="enter destination" id="destination" />
<input type="button" value="find" id="find" />
</div>
<br />
<div id ="map"style="width: 100%; top: auto; left: auto; position: relative; height: 600px; float:left" ></div>
This is perfectly worked one I checked it in firefox browser........:D
i'm trying to write a script that will get a user's geolocation - if they have it enabled, and plot a route to a predefined destination. if they don't have geolocation enabled, it should just plot the predefined location. the script isn't working, but you should be able to get a good idea of what i'm trying do do by looking through the code. am i on the right track? can anyone spot why it isn't working?
<script type="text/javascript">
$(function (){
var dest = "Unit 20, Tallaght Business Centre, Whitestown Road, Tallaght Business Park, Ireland";
if(geolocEnabled()){
getLocation();
}else{
plotMarker(dest);
}
//check if geolocation enabled
function geolocEnabled(){
return navigator.geolocation;
}
//plot marker for VRF office
function plotMarker(dest){
$('#map').gmap3(
{ action: 'addMarker',
address: dest,
map:{
center: true,
zoom: 14
},
marker:{
options:{
draggable: false
}
}
}
);
}
//get user's location
function getLocation(){
$('#map').gmap3(
{ action : 'geoLatLng',
callback : function(latLng){
if (latLng){
plotRoute(latLng, dest);
return;
} else {
alert("Unable to determine your location. Enable geolocation services and try again, or consult the map for our location.");
plotMarker(dest);
}
}
});
}
//plot route
function plotRoute(latLng, dest){
$('#map').gmap3(
{ action:'getRoute',
options:{
origin: latLng,
destination: dest,
travelMode: google.maps.DirectionsTravelMode.DRIVING
},
callback: function(results){
if (!results) return;
$(this).gmap3(
{ action:'init',
zoom: 7,
mapTypeId: google.maps.MapTypeId.ROADMAP,
streetViewControl: true,
center: [53.337433,-6.2661]
},
{ action:'addDirectionsRenderer',
panelID: 'directions-panel',
options:{
preserveViewport: true,
draggable: false,
directions:results
}
}
);
}
}
);
}
});
</script>
all help much appreciated.
EDIT: i'm not even getting a geolocation warning in-browser when i run the script.
EDIT: i removed the {timeout: 10000} from getLocation, it's now getting to the alert. script updated.
geolocating is an asynchronous process, the result will not be available yet when getLocation() is finished.
Call plotRoute() inside the callback of $.gmap3.geoLatLng and provide the expected arguments(latLng, dest)