I've just tried adding a main draggable marker on to the map. The issue I'm facing is that as soon as you drag that marker in black it creates a blue outline to one of the existing markers that are already placed on the map. I have no idea why it does this. I've isolated the bit of code where it's actually doing this, which is the click event listener that I've added to each marker, as soon as I remove this little snippet of code, it doesn't add a blue outline to any marker anymore. It's important to note, I've also tried commenting out the calls to the two inner function on this click handler however that doesn't seem to fix the issue, so it can't be those functions that are the cause.
It's also not a browser issue as the blue outline appears on both safari and chrome.
marker.addListener('click',
function() {
openCloseNav(true);
car_park_details(marker);
});
You can see the blue outline on the marker here (On the rightmost marker)
Most of the javascript I've added below.
var markers = [];
var geocoder;
var map;
var mainMarker;
function initMap() {
geocoder = new google.maps.Geocoder();
var defaultCoord = {
lat : 51.600960,
lng : -0.275770
};
map = new google.maps.Map(document.getElementById('map'), {
zoom : 15,
center : defaultCoord,
minZoom : 14,
streetViewControl : false,
controlSize : 33,
gestureHandling : 'greedy',
mapTypeControlOptions : {
mapTypeIds : []
},
styles : [ {
"featureType" : "all",
"elementType" : "all",
"stylers" : [ {
"hue" : "#008eff"
} ]
}, {
"featureType" : "road",
"elementType" : "all",
"stylers" : [ {
"saturation" : "0"
}, {
"lightness" : "0"
} ]
}, {
"featureType" : "transit",
"elementType" : "all",
"stylers" : [ {
"visibility" : "off"
} ]
}, {
"featureType" : "water",
"elementType" : "all",
"stylers" : [ {
"visibility" : "simplified"
}, {
"saturation" : "-60"
}, {
"lightness" : "-20"
} ]
} ]
});
mainMarker = new google.maps.Marker({
map,
position: defaultCoord,
draggable: true,
icon : {
url : 'mainmarker.png',
scaledSize : new google.maps.Size(30, 30),
origin : new google.maps.Point(0, 0),
}
});
google.maps.event.addListener(map, 'tilesloaded',
find_closest_markers);
google.maps.event.addListener(mainMarker, 'dragend',
find_closest_markers);
}
function geocodeEncapsulation(i) {
return (function(results, status) {
if (status == 'OK') {
var marker = new MarkerWithLabel({
map : map,
position : results[0].geometry.location,
icon : {
url : 'pin.png',
scaledSize : new google.maps.Size(40, 30),
//origin : new google.maps.Point(0, 0),
},
clickable: true,
labelContent : '£' + i.price.toFixed(2),
labelAnchor : new google.maps.Point(30, 35),
labelClass : "markerdesign",
labelInBackground : false,
title : i.name
});
marker.set("carpark", i);
marker.addListener('mouseover',
function() {
marker.set("labelClass",
"markerdesignhover");
});
marker.addListener('mouseout',
function() {
marker.set("labelClass", "markerdesign");
});
marker.addListener('click',
function() {
openCloseNav(true);
car_park_details(marker);
});
markers.push(marker);
} else {
//console.log(status);
}
});
}
Simplified Version On Fiddle, Drag the centre marker
http://jsfiddle.net/qn23wxmL/2/
Update:
Adding a separate click listener to the draggable marker solves the issue.
However I don't understand how this is working, if anyone can explain, that would be great.
Related
I'm trying to draw a line with polyline using angular-google-maps (doc here).
I'm not very familiar with AngularJS so I've got some difficuties to do what I want to do.
I'am able to print markers on the map with this function :
function addPosition (position, refresh) {
if (! _.mHas(position, "longitude", "latitude", "username")) {
console.log("That's not a proper position entry !");
return;
}
if (position.latitude === '' || position.longitude === '' ) return;
vm.map.markers.push({
id : vm.map.markers.length,
coords : {
longitude : position.longitude,
latitude : position.latitude
},
name : position.username,
options : {
icon : 'http://maps.google.com/mapfiles/ms/icons/blue-dot.png',
draggable : false
}
});
if (refresh) {
$timeout(function () {
vm.map.control.refresh();
}, 5);
}
}
I want to draw a Polyline between my markers but I don't have the good logic to take all coordinates from my markers and create a path with them.
I know I have to do something like :
function userLocation (position){
var lat = position.latitude;
var lng = position.longitude;
var pathLine = [new google.maps.LatLng(lat, lng)];}
And then draw the Polyline with something like this:
$scope.polylines = [{
path: pathLine,
stroke: {
color: '#000000',
weight: 3
},
editable: false,
draggable: false,
geodesic: true,
visible: true,
}];
With my "logic" i'm stuck in concept where I get coordinates forEach markers and it give me path results with : coordinates of my first marker and coordinates NULL, and , NULL coordinates and coordinates of my second marker.
I've created a JSFiddle with the code if you need here, without the $scope.Polyline.
Since you are utilizing angular-google-maps library and want
to draw a Polyline between my markers but I don't have the good logic
to take all coordinates from my markers and create a path with them.
and given that data for markers is represented in the following format:
[
{
id : vm.map.markers.length,
coords : {
longitude : position.longitude,
latitude : position.latitude
},
name : position.username,
options : {
icon : 'http://maps.google.com/mapfiles/ms/icons/blue-dot.png',
draggable : false
}
}
//...
]
data for Polyline could be generated like this:
vm.map.polyline = vm.map.markers.map(m => m.coords);
Example
angular
.module("mapApp", ["uiGmapgoogle-maps"])
.controller("mapCtrl", function($scope) {
vm = this;
vm.map = {
center: {
latitude: -24.9923319,
longitude: 125.2252427
},
zoom: 4,
lineStyle: {
color: "#333",
weight: 5,
opacity: 0.7
},
markers : [
{
coords: {
latitude: -33.8473567,
longitude: 150.6517955
},
name: "Sydney",
id: 1
},
{
coords: {
latitude: -37.9716929,
longitude: 144.772958
},
name: "Melbourne",
id: 3
},
{
coords: {
latitude: -34.9998826,
longitude: 138.3309812
},
name: "Adelaide",
id: 4
},
{
coords: {
latitude: -32.0391738,
longitude: 115.6813556
},
name: "Perth",
id: 5
},
{
coords: {
latitude: -12.425724,
longitude: 130.8632684
},
name: "Darwin",
id: 6
},
{
coords: {
latitude: -16.8801503,
longitude: 145.5768602
},
name: "Cairns",
id: 7
}
],
};
vm.map.polyline = vm.map.markers.map(m => m.coords);
});
.angular-google-map-container {
position: absolute;
top: 0;
bottom: 0;
right: 0;
left: 0;
}
<script src="https://code.angularjs.org/1.3.14/angular.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.js"></script>
<script src="https://rawgit.com/angular-ui/angular-google-maps/2.0.X/dist/angular-google-maps.js"></script>
<div ng-app="mapApp" ng-controller="mapCtrl as vm">
<ui-gmap-google-map
center='vm.map.center'
zoom='vm.map.zoom'>
<ui-gmap-markers models="vm.map.markers" coords="'coords'" idkey="'id'" ></ui-gmap-markers>
<ui-gmap-polyline path="vm.map.polyline" draggable="false" geodesic="true" stroke="vm.map.lineStyle" fit="false"></ui-gmap-polyline>
</ui-gmap-google-map>
</div>
This is my GeoJson :
{
"type" : "FeatureCollection",
"created" : "2014/07/08 03:00:55 GMT",
"announced_date" : "2017/07/10 03:00:55 GMT",
"features" : [{
"type" : "Feature",
"properties" : {
"name" : "n18",
"analized_date" : "2013/07/08 10:00:00 GMT"
},
"geometry" : {
"type" : "GeometryCollection",
"geometries" : [{
"type" : "Point",
"coordinates" : [134.7, 37.3]
}, {
"type" : "LineString",
"coordinates" : [[134.7, 37.3], [134.6, 37.1]]
}
]
}
}]
}
I can display it in normal line but I want display as dashed line .
I google and there is a way : use Polyline but I don't know how to convert it to Polyline .
Please help . Thank you :) .
To make the poly line dashed, you have to create a native google.maps.Polyline object. One way to do that is to use the data layer to load the GeoJSON, then use its methods to create the polyline from the GeoJSON:
code snippet:
function initialize() {
// Create a simple map.
map = new google.maps.Map(document.getElementById('map-canvas'), {
zoom: 8,
center: {
lat: 37,
lng: 134
}
});
google.maps.event.addListener(map, 'click', function() {
infowindow.close();
});
// process the loaded GeoJSON data.
google.maps.event.addListener(map.data, 'addfeature', function(e) {
if (e.feature.getGeometry().getType() === 'GeometryCollection') {
var geometry = e.feature.getGeometry().getArray();
for (var i = 0; i < geometry.length; i++) {
if (geometry[i].getType() === 'Point') {
map.setCenter(geometry[i].get());
new google.maps.Marker({
map: map,
position: geometry[i].get()
});
} else if (geometry[i].getType() === 'LineString') {
new google.maps.Polyline({
map: map,
path: geometry[i].getArray(),
// make the polyline dashed. From the example in the documentation:
// https://developers.google.com/maps/documentation/javascript/examples/overlay-symbol-dashed
strokeOpacity: 0,
icons: [{
icon: {
path: 'M 0,-1 0,1',
strokeOpacity: 1,
scale: 4
},
offset: '0',
repeat: '20px'
}]
})
}
}
}
map.data.setMap(null);
});
map.data.addGeoJson(data);
}
google.maps.event.addDomListener(window, 'load', initialize);
var data = {
"type" : "FeatureCollection",
"created" : "2014/07/08 03:00:55 GMT",
"announced_date" : "2017/07/10 03:00:55 GMT",
"features" : [{
"type" : "Feature",
"properties" : {
"name" : "n18",
"analized_date" : "2013/07/08 10:00:00 GMT"
},
"geometry" : {
"type" : "GeometryCollection",
"geometries" : [{
"type" : "Point",
"coordinates" : [134.7, 37.3]
}, {
"type" : "LineString",
"coordinates" : [[134.7, 37.3], [134.6, 37.1]]
}
]
}
}]
};
html,
body {
height: 100%;
margin: 0px;
padding: 0px;
width: 100%;
}
#map-canvas {
height: 100%;
width: 100%;
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="map-canvas"></div>
I am creating a Google map with multiple markers that I want to popup into a Fancybox lightbox when clicked on. I must admit, I am quite a novice at javascript and Google Maps API.
I have put some pieces of different sample scripts together and come up with something that actually works decently. I have the markers the way I want them (well, without captions... which I still have to figure out), the style of map the way I want it, and I even have the markers popping up lightboxes when clicked on.
However, all markers end up opening one URL in the lightbox. I guess that makes a bit of sense. The Fancybox code is being distributed to all the markers, instead of each one individually. I tried to make another argument with a url and pass it into the Fancybox script, but it still just picks up the last marker's url and uses it for all the markers. How would I be able to get the URL to work for each marker instead of all the markers at once?
I did find a similar question on here:
Multiple fancybox google map
However, it seams to use a different route of attacking the same issue. Plus, I can't seem to get their script to work by itself, let alone integrate it with my code. So, while I get how the solution works for them, it doesn't seem to help me.
My code is as follows:
var map;
var MY_MAPTYPE_ID = 'custom_style';
function initialize() {
var featureOpts = [
{
stylers: [
{ hue: '#CCCCCC' },
{ saturation: '-100' },
{ visibility: 'simplified' },
{ gamma: 2 },
{ weight: .4 }
]
},
{
elementType: 'labels',
stylers: [
{ visibility: 'off' }
]
},
{
featureType: 'water',
stylers: [
{ color: '#efefef' }
]
}
];
var mapOptions = {
zoom: 9,
scrollwheel: false,
keyboardShortcuts: false,
disableDefaultUI: true,
center: new google.maps.LatLng(34.0531553, -84.3615928),
mapTypeControlOptions: {
mapTypeIds: [google.maps.MapTypeId.ROADMAP, MY_MAPTYPE_ID]
},
mapTypeId: MY_MAPTYPE_ID
};
map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
var styledMapOptions = {
name: 'Custom Style'
};
var customMapType = new google.maps.StyledMapType(featureOpts, styledMapOptions);
map.mapTypes.set(MY_MAPTYPE_ID, customMapType);
setMarkers(map, schools);
}
var schools = [
['Canton', 34.2352063, -84.4846274, 4, 'popup.htm'],
['Austell', 33.8158106, -84.6334938999999, 3, 'popup.htm'],
['Marietta', 33.9578674, -84.5532791, 2, 'popup.htm'],
['Atlanta', 33.7635085, -84.43030209999999, 1, 'popup2.htm']
];
function setMarkers(map, locations) {
var image = {
url: 'images/fml-home.png',
size: new google.maps.Size(67, 63),
origin: new google.maps.Point(0,0),
anchor: new google.maps.Point(0, 63)
};
var shadow = {
url: 'images/fml-shadow.png',
size: new google.maps.Size(45, 18),
origin: new google.maps.Point(0,0),
anchor: new google.maps.Point(0, 18)
};
var shape = {
coord: [1, 1, 1, 67, 60, 67, 60 , 1],
type: 'poly'
};
for (var i = 0; i < locations.length; i++) {
var schools = locations[i];
var myLatLng = new google.maps.LatLng(schools[1], schools[2]);
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
shadow: shadow,
icon: image,
shape: shape,
title: schools[0],
zIndex: schools[3]
});
var href = schools[4];
google.maps.event.addListener(marker, 'click', function() {
$.fancybox({
frameWidth : 800,
frameHeight : 600,
href : href,
type : 'iframe'
});
});
}
}
google.maps.event.addDomListener(window, 'load', initialize);
Try this:
marker["href"] = schools[4];
google.maps.event.addListener(marker, 'click', function() {
$.fancybox({
frameWidth : 800,
frameHeight : 600,
href : this.href,
type : 'iframe'
});
});
I've a simple gmappanel (extjs 4.1.1).
How to change the "center" of the map and refresh my window with the center in new coordinate?
My code is:
Ext.Loader.setConfig({
enabled : true
});
Ext.require(['Ext.window.*', 'Ext.ux.GMapPanel']);
Ext.define('AM.view.gmapwindow.GoogleMap', {
extend : 'Ext.window.Window',
alias : 'widget.gmapw',
autoShow : true,
title : 'map',
closeAction : 'hide',
width : 460,
height : 500,
border : false,
x : 40,
y : 60,
items : [{
layout : {
type : 'hbox',
align : 'stretch'
},
flex : 1,
items : [{
xtype : 'textfield'
}, {
xtype : 'button',
handler: function() {
//--------------------
//modify here the center
//geoCodeAddr:'Suisse Romande, Avenue de la Gare, Sion, Svizzera'
//---------------------
}
}]
}, {
width : 450,
layout : 'fit',
height : 450,
border : false,
items : {
xtype : 'gmappanel',
center : {
geoCodeAddr : '4 Yawkey Way, Boston, MA, 02215-3409, USA'
},
markers : []
}
}]
});
the map is well shown, but if i try to change the center editing
geoCodeAddr
with the following code
this.up('gmapw').down('gmappanel').center.geoCodeAddr='Suisse Romande, Avenue de la Gare, Sion, Svizzera';
nothing happens.
any ideas?
Thank you
If you look at GMapPanel.js, you will see that in afterFirstLayout(), geoCodeAddr is used when creating the map. Setting it after layout is not going to do anything since afterFirstLayout() won't be called again.
You should geocode your address and use that to set the center on the map. Something like the following should work:
var map = this.gmap;
var geocoder = new google.maps.Geocoder();
var request = {address: 'Suisse Romande, Avenue de la Gare, Sion, Svizzera'};
var callBack = function(geocoderResults, geocoderStatus) {
if(geocoderStatus === 'OK') {
var location = geocoderResults[0].geometry.location;
var latLng = new google.maps.LatLng(location.lat(), location.lng());
map.setCenter(latLng);
}
}
geocoder.geocode(request,callBack);
I've modify Arun V answer to make it full working for my example.
Thank you again Arun V:
var request = {address: 'Suisse Romande, Avenue de la Gare, Sion, Svizzera'};
var callBack = function(geocoderResults, geocoderStatus) {
if(geocoderStatus === 'OK') {
var location = geocoderResults[0].geometry.location;
var latLng = new google.maps.LatLng(location.lat(), location.lng());
//get current Id from document useful if you have more than one map
//you can't use "this.gmap" reference here because it's not in your scope
var idMapW = this.document.activeElement.id;
Ext.ComponentQuery.query('#'+idMapW)[0].down('gmappanel').gmap.setCenter(latLng);
}
};
this.up('gmapw').down('gmappanel').geocoder.geocode(request,callBack);
I am building an app which contains a list of addresses. This app is working in such a way that once the user clicks on each of the items (addresses) in the list, the next page shows a map, and the map has a marker which points to the exact location of the address clicked on. This is made possible due to the Latitude and Longitude coordinates stated in code.
My problem is that I have more than one address, and each of these addresses have a unique longitude and latitude. I want to make my app work in such a way that when a user clicks on any address they are interested in, the app will open a page and show the map and a marker pointing to the exact location of the address on the map. My code's below: it is working perfectly, BUT when the user clicks on the address, it takes them to the same logitude and latitude.
My store:
Ext.define('List.store.Presidents', {
extend : 'Ext.data.Store',
config : {
model : 'List.model.President',
sorters : 'lastName',
grouper : function(record) {
return record.get('lastName')[0];
},
data : [{
firstName : "Ikhlas HQ",
lastName : "Tower 11A, Avenue 5, Bangsar South, No.8 Jalan Kerinchi 59200 Kuala Lumpur",
latitude : 3.110649,
longitude : 101.664991,
id: 'm12',
},
{
firstName : "PEJABAT WILAYAH SELANGOR",
lastName : "No. 97, 97-1 & 97-2, Jalan Mahogani 5/KS7, Ambang Botanic, 41200 Klang, Selangor",
latitude : 3.003384,
longitude : 101.45256,
id: 'm1',
}, ]
}
});
My controller:
Ext.define('List.controller.Main', {
extend: 'Ext.app.Controller',
config: {
control: {
'presidentlist': {
disclose: 'showDetail'
},
}
},
showDetail: function(list, record) {
this.getMain().push({
xtype: 'presidentdetail',
title: record.fullName(),
listeners: {
maprender: function(comp, map) {
var position = new google.maps.LatLng(5.978132,116.072617);
var marker = new google.maps.Marker({
position: position,
map: map
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map, marker);
});
setTimeout(function() {
map.panTo(position);
}, 1000);
},
},
})
},
});
My view:
Ext.define('List.view.PresidentDetail', {
extend : 'Ext.Map',
xtype: 'presidentdetail',
config: {
title: 'Details',
styleHtmlContent: true,
scrollable: 'vertical',
//useCurrentLocation: true,
layout: 'fit',
mapOptions: {
zoom: 16,
mapTypeId: google.maps.MapTypeId.ROADMAP,
navigationControl: true,
navigationControlOptions: {
style: google.maps.NavigationControlStyle.DEFAULT
}
},
}
});
My model:
Ext.define('List.model.President', {
extend : 'Ext.data.Model',
config : {
fields : ['firstName', 'middleInitial', 'lastName', 'latitude', 'longitude']
},
fullName : function() {
var d = this.data, names = [d.firstName, (!d.middleInitial ? "" : d.middleInitial + "."), d.lastName];
return names.join(" ");
}
});
Help me out please. I need each of the addresses on the list to be tagged with a latitude and longitude so that when the user clicks on the address, it will point to the exact location the map.
Your line:
var position = new google.maps.LatLng(5.978132,116.072617);
Is fixed to the same coordinates so it will never change.
In my application I have the view fire an event to the controller and then in the controller have a reference to the record's coordinates which are then set to the map.
In view:
config: {
layout: 'fit',
items: [
{
xtype: 'map',
listeners: {
maprender: function (extMapComponent, googleMapComp) {
this.fireEvent('googleMapRender', googleMapComp);
}
}
}
]
}
Controller:
refs: {
mapRef: 'map'
},
Control: {
mapRef: {
googleMapRender: 'onGoogleMapRender'
}
}
onGoogleMapRender: function (googleMap) {
// this.selectedRecord should be set when you select the item in the list
// so that you can pull the coordinates off
var record = this.selectedRecord;
var long = record.get("Longitude");
var lat = record.get("Latitude");
var marker = new google.maps.Marker({
position: new google.maps.LatLng(lat, long);
});
marker.setMap(googleMap);
}