google map info window data display - infowindow

I have error about for info window data. I can't get the Please help me to check my code.
function initialize() {
map = new google.maps.Map(document.getElementById(map), {
center: new google.maps.LatLng(1.352083, 103.819836),
zoom: 12,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
//var infowindow;
if (markers) {
for (var level in markers) {
for (var i = 0; i < markers[level].length; i++) {
var details = markers[level][i];
//var infowindow;
markers[level][i] = new google.maps.Marker({
title: details.name,
position: new google.maps.LatLng(
details.location[0], details.location[1]),
clickable: true,
draggable: false,
icon: details.icon
});
var infowindow = new google.maps.InfoWindow({
content: details.description,
//content : markers[level][i].description,
position: new google.maps.LatLng(details.location[0], details.location[1])
//position: markers[level][i].position
});
google.maps.event.addListener(markers[level][i], 'click', function() {
infowindow.setPosition(this.position);
alert(this.position);
//infowindow.setContent(markers[level][i].description);
infowindow.open(map,markers[level][i]);
});
}
}
}
I can't get the description data. Please help me to check my code.

Related

How to stop cursor flickering over mapbox marker icons?

How do I stop cursor flickering over my Mapbox icons? Here is the live site where you can see the problem when hovering over the marker icons: https://rustic-waters-group.thesparksite.com/lakes/
Here is my code:
mapboxgl.accessToken = 'pk.eyJ1IjoiZG1pdHJpbWFydGluIiwiYSI6ImNreHRobHRmcjVqM3cydmt5NWkxdWNibTcifQ.CuN5Dwc963TW-BKRcowxBA';
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/dmitrimartin/ckxtj5aur4fvv15mrhmihala8',
center: [-89.2, 44.33],
zoom: 9.2
});
map.on('load', () => {
const popup = new mapboxgl.Popup({
closeButton: false,
closeOnClick: false
});
map.on('mouseenter', 'lakes', (event) => {
map.getCanvas().style.cursor = 'pointer';
const features = map.queryRenderedFeatures(event.point, {
layers: ['lakes']
});
if (event.features.length === 0) return;
popup.setLngLat(features[0].geometry.coordinates);
popup.setHTML('<h3 class="lake-popup">' + features[0].properties.title + '</h3>');
popup.setMaxWidth("calc(100vw - 40px);");
popup.addTo(map);
});
map.on('mouseleave', 'lakes', () => {
map.getCanvas().style.cursor = '';
popup.remove();
});
map.on('click', 'lakes', (event) => {
const features = map.queryRenderedFeatures(event.point, {
layers: ['lakes']
});
if (event.features.length === 0) return;
window.location.href = ('/lakes/' + features[0].properties.url + '/');
});
document.getElementById("lakes-header").onmouseover = function() {
MyMouseOver();
};
function MyMouseOver() {
document.getElementById("wrapper").style.display = "none";
document.getElementById("lakes-header").style.display = "none";
}
});
The issue stems from the popup box on top of the layer and can be fixed by adding the CSS property 'cursor-events: none' to the popup. That should stop the flickering and shouldn't interfere with the layers.

infobox to pushpin via geocode, close all open infoboxs before opening new infobox

ok, here is my code
const members = [
{name: 'Abc Ijk', order: '646545', duration: '1.20h', createdOn: '02/03/2021 09:00 - 10:00', address: '1221 test Avenue Room 112 Portland OR 97204' },
{name: 'Xyz Opq', order: '646546', duration: '3.00h', createdOn: '02/03/2021 08:00 - 11:00', address: '945 nw street 852 Portland OR 97209' }
];
function loadEmpStatus() {
// var navigationBarMode = Microsoft.Maps.NavigationBarMode;
var map = new Microsoft.Maps.Map(document.getElementById('sdy-fserv-map'), {
/* No need to set credentials if already passed in URL */
// navigationBarMode: navigationBarMode.compact,
// supportedMapTypes: [Microsoft.Maps.MapTypeId.road, Microsoft.Maps.MapTypeId.aerial, Microsoft.Maps.MapTypeId.grayscale, Microsoft.Maps.MapTypeId.canvasLight],
supportedMapTypes: [Microsoft.Maps.MapTypeId.road, Microsoft.Maps.MapTypeId.aerial],
center: new Microsoft.Maps.Location(47.624527, -122.355255),
maxZoom: 11,
minZoom: 5
});
for( let row of members ) {
console.log(row);
doGeocode( map, row );
}
}
function doGeocode( map, data ) {
Microsoft.Maps.loadModule('Microsoft.Maps.Search', function () {
var searchManager = new Microsoft.Maps.Search.SearchManager(map);
var requestOptions = {
bounds: map.getBounds(),
where: data.address,
callback: function (answer, userData) {
map.setView({ bounds: answer.results[0].bestView });
var pushpin = new Microsoft.Maps.Pushpin(answer.results[0].location, {
icon: 'https://www.bingmapsportal.com/Content/images/poi_custom.png',
});
// map.entities.push(new Microsoft.Maps.Pushpin(answer.results[0].location));
map.entities.push(pushpin);
var infobox = new Microsoft.Maps.Infobox(answer.results[0].location, {
title: data.name,
description: data.address, visible: false,
actions: [
{ label: 'Handler1', eventHandler: function () { console.log('Handler1'); } },
{ label: 'Handler2', eventHandler: function () { console.log('Handler2'); } },
]
});
infobox.setMap(map);
Microsoft.Maps.Events.addHandler(pushpin, 'click', function () {
infobox.setOptions({ visible: true });
});
map.entities.push(pushpin);/**/
}
};
searchManager.geocode(requestOptions);
});
}
it runs smoothly and I have geocoded pushpins with infoboxes attached and showing up nicely.
But I am failing to figure out how to make all opened infoboxes close before opening new infobox on pushpin click event.
Please help..
I highly recommend creating a single infobox and reusing it as outline in this document: https://learn.microsoft.com/en-us/bingmaps/v8-web-control/map-control-concepts/infoboxes/multiple-pushpins-and-infoboxes

Integrating WFS as gml in OL5

I try to visualize a WFS (from MapServer) in OL5.
The WFS works well (I can implement it without any problems in QGIS).
Also a request like:
http://blablabla/mapserv?service=WFS&version=1.1.0&request=GetFeature&typename=Flurstueckepunkt&srsname=EPSG:25832&bbox=411554,5791886,411677,5792008
gives me a nice gml-Output in epsg: 25832.
I try to implement it in OpenLayers like:
var vectorSource = new VectorSource({
format: new WFS(),
loader: function(extent, resolution, projection) {
var url = 'http://blablabla/mapserv?service=WFS&version=1.1.0&request=GetFeature&typename=ms:Flurstueckepunkt&srsname=EPSG:25832&bbox=412200,5791337,413600,5791800,EPSG:25832'
fetch(url).then(function(response) {
return response.text();
}).then(function(text) {
var features = vectorSource.getFormat().readFeatures(text);
// Add parsed features to vectorSource
vectorSource.addFeatures(features);
}).catch(function(error) {
alert(error.message);
})
}
});
var WFSLayer =new VectorLayer(
{
source: vectorSource,
projection: 'EPSG:25832',
style: new Style({ fill: new Fill({ color: 'yellow' })
})
});
var view = new View({
center: [rechtswert,hochwert],
zoom: mzoom,
projection: 'EPSG:25832'
});
var map = new Map({
layers: [osm,wmsLayer2,WFSLayer],
target: 'map',
view: view
});
...but the WFS-Layer is not shown at all.
Via the Mozialle-Debugger I can see, that the wfs-request workes, but nothing is visualized?
Has anybody an idea what is wrong here?
Allright, I got it. As the WFS ist delivering points the visualisation-style is important.
It workes now with:
var vectorSource = new Vector({
format: new GML3(),
loader: function(extent) {
var url = 'http://blablalbvlAn/cgi-bin/mapserv?service=WFS&version=1.1.0&request=GetFeature&typename=ms:Flurstueckepunkt&srsname=EPSG:25832&' +
'bbox='+ extent.join(',') +',EPSG:25832';
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
var onError = function() {
vectorSource.removeLoadedExtent(extent);
}
xhr.onerror = onError;
xhr.onload = function() {
if (xhr.status == 200) {
vectorSource.addFeatures(
vectorSource.getFormat().readFeatures(xhr.responseText));
var features3 = vectorSource.getFeatures();
} else {
onError();
}
}
xhr.send();
},
strategy: bbox
});
var WFSLayer =new VectorLayer(
{
source: vectorSource,
style: new Style({
image: new CircleStyle({
radius: 5,
fill: new Fill({
color: 'orange'
})
})
})
});

Google Markers with dynamic data for Ionic Modal

I am new to hybrid mobile app creation. And my use case is very simple. I have a single ionic modal using template html.
What I want is populating the same ionic template with different values based on some records data. Basically it is a google map and on click on any of the markers, the same template should open with different values based on the marker.
My controller code -
.controller('MyLocationCtrl', function(
$scope,
$stateParams,
force,
$cordovaGeolocation,
$ionicModal,
GoogleMapService,
ForceService,
$q
) {
console.log('this is in my location page');
var currentPosition = GoogleMapService.getCurrentLocation();
var restaurantModal = $ionicModal.fromTemplateUrl('templates/bottom-sheet.html', {
scope: $scope,
viewType: 'bottom-sheet',
animation: 'slide-in-up'
});
var allContacts = ForceService.getAllContactsWithGeo();
var promises = [];
promises.push(currentPosition);
promises.push(allContacts);
promises.push(restaurantModal);
var allMarkers = [];
var allContactDetails = [];
currentPosition.then(
function(position) {
console.log('position data -->', position);
var latLng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
var mapOptions = {
center: latLng,
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
$scope.map = new google.maps.Map(document.getElementById("map"), mapOptions);
var bounds = new google.maps.LatLngBounds();
allContacts.then(
function(contacts) {
console.log('contacts final -->', contacts);
for (var i=0; i<contacts.records.length; i++) {
var contact = contacts.records[i];
console.log('single contact -->', contact.MailingLatitude, contact.MailingLongitude);
var contactlatLng = new google.maps.LatLng(contact.MailingLatitude, contact.MailingLongitude);
var contactInfo = {};
//contactInfo.marker = {};
var marker = new google.maps.Marker({
map: $scope.map,
animation: google.maps.Animation.DROP,
position: contactlatLng
});
contactInfo.marker = marker;
contactInfo.recordDetails = contact;
allMarkers.push(marker);
allContactDetails.push(contactInfo);
// Set boundary for markers in map
bounds.extend(contactlatLng);
}
// Fit map based on markers
$scope.map.fitBounds(bounds);
}
);
// google.maps.event.addListenerOnce($scope.map, 'idle', function(){
// });
},
function(error) {
console.log("Could not get location" + error);
}
);
// Add listener for marker pop up once all promises resolved
$q.all(promises).then(
function(values) {
console.log('first -->', values[0]);
console.log('second -->', values[1]);
console.log('third -->', values[2]);
var detailModal = values[2];
$scope.modal = detailModal;
for (var i=0; i<allContactDetails.length; i++) {
allContactDetails[i].marker.addListener('click', function() {
console.log('helllos from marker');
console.log('all contactInfo -->', allContactDetails[i].recordDetails.Name);
$scope.contactName = allContactDetails[i].recordDetails.Name;
detailModal.show();
});
}
}
);
})
Front end template code -
<script id="templates/bottom-sheet.html" type="text/ng-template">
<ion-bottom-sheet-view>
<ion-header-bar align-title="left">
<h1 class="title">New Particle</h1>
<button class="button button-icon icon ion-android-close" ng-click="modal.hide()"></button>
{{contactName}}
</ion-header-bar>
</ion-bottom-sheet-view>
</script>
Now the modal opens properly when i click on the google marker, but I am not sure how to pass dynamic data to the pop modal.
Since you are doing this :
var restaurantModal = $ionicModal.fromTemplateUrl('templates/bottom-sheet.html', {
scope: $scope,
viewType: 'bottom-sheet',
animation: 'slide-in-up'
});
Your modal can access to the scope of your controller.
So if you declare any variable in your controller it will be accessible through the modal.

Leafletjs: How to have new marker in first click then update the latlng of marker in second click

I have list of markers that want to render in the map, but I want it one by one. In first click I want to make new marker. Then when I click to another location, I want my marker to just move to the new latLng not to create another marker. Here is my code:
function (licon, coord, data) {
var self = jQuery(this);
var map = self.data("map");
var latlng = new L.LatLng(coord[0], coord[1]);
//Create Marker
if (licon) {
var leafIcon = L.icon(licon);
console.log(typeof (marker));
if (typeof (marker) === 'undefined') {
var marker = L.marker(latlng, {
icon: leafIcon,
"markerData": data,
draggable: true
});
} else {
console.log('not undefined');
map.removeLayer(marker);
marker = L.marker(latlng, {
icon: leafIcon,
"markerData": data,
draggable: true
});
}
} else {
var marker = L.marker(latlng, {
"markerData": data,
draggable: true
});
}
marker.addTo(map);
return marker;
}
A quick example of the result: http://jsfiddle.net/ve2huzxw/43/
var currentMarker;
map.on("click", function (event) {
if (currentMarker) {
currentMarker.setLatLng(event.latlng);
return;
}
currentMarker = L.marker(event.latlng, {
draggable: true
}).addTo(map).on("click", function () {
event.originalEvent.stopPropagation();
});
});
document.getElementById("done").addEventListener("click", function () {
currentMarker = null;
});
You can also add a smooth transition to show the marker moving to the new position:
if (currentMarker) {
currentMarker._icon.style.transition = "transform 0.3s ease-out";
currentMarker._shadow.style.transition = "transform 0.3s ease-out";
currentMarker.setLatLng(event.latlng);
setTimeout(function () {
currentMarker._icon.style.transition = null;
currentMarker._shadow.style.transition = null;
}, 300);
return;
}
a slightly more consolidated solution some years later.
var currentMarker;
map2.on('click', function(e) {
if (currentMarker){
currentMarker.setLatLng(e.latlng)
} else {
currentMarker = new L.marker(e.latlng).addTo(map2);
};
//console.log('lat, lon: ', e.latlng.lat, e.latlng.lng);
});
leaflet now defaults to smoothly dragging the point over to the new coords.