I am relative new to Angularjs and i am currently working on a project but I hit an obstacle. I've been trying multiple ways to do this but Im all out of idea. Here is a picture of what I want to do:
Map
So on this picture, there are icons and what I want to do is upon clicking an icon, a pop-up window will appear. If you look at the shaded area on top right, that is how I want my the window to be and look like as I already built a template for it and right now the template is static div being displayed.
Here is my code so far:
$scope.cameraData = [];
$scope.markers = [];
$http.get($scope.docRoot + 'public/data/streetcams.json')
.success(function(data) {
$scope.cameraData = data;
for(var marker in $scope.cameraData) {
if($scope.cameraData.hasOwnProperty(marker)) {
$scope.cameraData[marker].icon = cameraIcon;
$scope.cameraData[marker].layer = 'video';
}
}
$scope.markers = $scope.cameraData;
}).error(function(data) {
console.log("Unable to load streecam data file");
});
$scope.windowOption = {
show:false
};
var x, y;
$scope.$on("leafletDirectiveMarker.map.click", function(event, args) {
console.log("this is where the marker is");
console.log (args.latlng.lat, args.latlng.lng);
for ( var marker in $scope.markers) {
x = args.latlng.lat;
y = args.latlng.lng;
if (marker.lat === x && marker.lng === y ) {
$scope.windowOption.show = !$scope.windowOption.show;
}
}*/
});
$scope.closePopupOnClick = function () {
$scope.windowOption.show = false;
};
So $scope.markers contains the information of all icons (title, lat and longitude) and my idea is to retrieve the latitude and longitude of each click event and compare that with latitude and longitude of each marker in the markers array, if they are equal then show to popup window. But it's not working and Im not sure what else to do. Any tips will help!
Thanks!
Related
I built a photo map with leaflet js which contains geotagged photos. I managed to fetch the timestamp and coordinates of the pictures with a php script and now I want to filter the images by it's recording date. The metadata of the imported images contain information about Year, Year.Month and Year.Month.Day.
This is my leaflet setup:
var photoLayer = L.photo.cluster({ spiderfyDistanceMultiplier: 1.2 }).on('click', function (evt) {
evt.layer.bindPopup(L.Util.template('<span class="DatumPopup">Aufnahmedatum: {DateTimeOriginal} <span class="Uhrzeit">{Time}</span><img src="{url}" height="auto" width="100%"/>', evt.layer.photo), {
className: 'leaflet-popup-photo',
minWidth: 400
}).openPopup();
});
//Call the next function as soon as the page loads
window.onload = callForImages()
//Makes a request, loading the getimages.php file
function callForImages() {
//Create the request object
var httpReq = (window.XMLHttpRequest)?new XMLHttpRequest():new ActiveXObject("Microsoft.XMLHTTP");
//When it loads,
httpReq.onload = function() {
//Convert the result back into JSON
var result = JSON.parse(httpReq.responseText);
//Load the images
loadImages(result);
}
//Request the page
try {
httpReq.open("GET", "getphotos.php", true);
httpReq.send(null);
} catch(e) {
console.log(e);
}
}
//Generates the images and sticks them into the photolayer
function loadImages(images) {
var photos = [];
//Loop over the images
for(var i = 0; i < images.length; i++) {
photos.push({
lat: images[i].lat,
lng: images[i].lng,
url: images[i].filename,
DateTimeOriginal: images[i].DateTimeOriginal,
Year: images[i].Year,
YearMonth: images[i].YearMonth,
Time: images[i].Time,
//If you have thumbnails, switch the comments on the following lines.
thumbnail: images[i].filename
//thumbnail: images[i].thumbnail
});
}
photoLayer.add(photos).addTo(map);
//Add the photos to the map
map.fitBounds(photoLayer.getBounds());
//Zoom the map to the photos
}
}).addTo( map );
I have a hard time wrapping my head around how to apply the filter with the layer control. Since I used leaflet.photo to import the pictures, I don't even know hot wo apply a classic layer control to this project. Anyone who could give me a hint in the right direction?
im using OpenLayers 5 to display two different layers on the same map. I can see both Markers on the Map with different icons. The code below writes in the popup of one layer. Now my question is: how can i display different Infos on the Popup for each specific layer. For example when the mouse is over the first icon the popup should contain the name of the first layer and when it is over the second different icon it shows the name of the second layer.
I assume i should use map.getFeaturesAtPixel(event.pixel, function (layer1)) or something like this but im facing problems right there
//display the pop with on mouse over event
map.on('pointermove', function (event) {
const features = map.getFeaturesAtPixel(event.pixel);
if (features.length > 0 ) {
var coordinate = event.coordinate;
//get the infos that are going to be displayed in the Pop-up window;
const layerOneName = features[0].get('vehName');
// text written inside the popup
content.innerHTML = '<b>'+layerOneName +'</b>';
overlay.setPosition(coordinate);
}
});
If you use forEachFeatureAtPixel use can add a layer filter function and use that to set the layer
map.on('pointermove', function (event) {
let layer;
const feature = map.forEachFeatureAtPixel(
event.pixel,
function (feature) {
return feature;
},
{
layerFilter: function (candidate) {
layer = candidate;
return true;
}
}
);
if (feature) {
var coordinate = event.coordinate;
//get the infos that are going to be displayed in the Pop-up window;
const layerOneName = feature.get('vehName');
// text written inside the popup
content.innerHTML = '<b>'+layerOneName +'</b>';
overlay.setPosition(coordinate);
}
});
I have an issue with a Mapbox map where Popups attached to a Marker are displayed the wrong position, when the map is zoomed out, so we see multiple world copies. See sample below. The Popup are displayed at the correct position when the map is zoomed in and only one world is visible.
This is a simplified version of the code used to add Markers + Popups and display them:
// Add markers to the map
features.forEach(function (marker: any, i: number) {
const popUpContent = '<div>Sample</div>'
// Create the popup
const popup = new mapboxgl.Popup({ offset: 25 })
.setHTML(popUpContent)
.on('open', function (event: any) {
const activePoi = document.getElementsByClassName(poiId)[0]
activePoi.classList.add('active')
})
.on('close', function () {
const activePoi = document.getElementsByClassName(poiId)[0]
if (activePoi) {
activePoi.classList.remove('active')
}
})
let mark = new mapboxgl.Marker(markerElement)
.setLngLat(marker.geometry.coordinates)
.setPopup(popup)
.addTo(map)
})
Question
How can I solve this issue, so that popup appears correctly above their respective Marker, even when multiple world copies are visible?
You can use Mapbox's solution to this: https://docs.mapbox.com/mapbox-gl-js/example/popup-on-click/
// When a click event occurs on a feature in the places layer, open a popup at the
// location of the feature, with description HTML from its properties.
map.on('click', 'places', function(e) {
var coordinates = e.features[0].geometry.coordinates.slice();
var description = e.features[0].properties.description;
// Ensure that if the map is zoomed out such that multiple
// copies of the feature are visible, the popup appears
// over the copy being pointed to.
while (Math.abs(e.lngLat.lng - coordinates[0]) > 180) {
coordinates[0] += e.lngLat.lng > coordinates[0] ? 360 : -360;
}
new mapboxgl.Popup()
.setLngLat(coordinates)
.setHTML(description)
.addTo(map);
});
// ...
}
I am trying to add custom results to autocomplete and am having some luck, but I cannot make the results clickable. A left or right click does absolutely nothing. Consider the following code:
<input type="text" name="query" id="query">
<script>
var input = (document.getElementById('query'));
var options = [];
city = new google.maps.places.Autocomplete(input, options);
google.maps.event.addListener(city, 'place_changed', function () {
place = city.getPlace();
});
$("#query").on('input', function()
{
append_places($("#query").val());
});
var new_pac = false;
function append_places(input)
{
if (!new_pac)
{
setTimeout(function()
{
$(".pac-container").append('<div id="new-pac""></div>');
}, 1);
new_pac = true;
}
else
{
$('#new-pac').empty();
}
$("#new-pac").append('<div class="pac-item areasearch">Foo<span class="pac-icon pac-icon-areas"></span><a class="pac-item-query" href="http://www.wherever.com">test</a></div>');
}
</script>
The new entry shows up, looks like a link, but doesn't react when clicked. Any ideas on how to make this happen?
Looking at the Google Maps JS Demo it seems that you are lacking a method to define the preferred viewport on the map to view the place. You need to add code where it will do something wether or not it was able to retrieve a place.
// If the place has a geometry, then present it on a map.
if (place.geometry.viewport) {
map.fitBounds(place.geometry.viewport);
}
Here's another example for reference.
I am using the Geolocation Marker Script from the Google Maps Utilities Library V3 in order to display the position of a user.
What I want to achieve (I am a newbie to the Google Maps API!) is:
have the users current coordinates displayed (e.g. in a simple CSS container somewhere on the page)
connect an event to a marker. I should be triggered when the user is close.
Appreciate your help!
To display coordinates to the user, you would need a reference to a DOM Element. Then it's a simple matter of updating the content.
HTML On the Page
<div id="UserCoordinates">Waiting on GPS Position ...</div>
In Script
google.maps.event.addListener(GeoMarker, 'position_changed', function() {
var UserPosition = this.getPosition();
var DisplayElement = document.getElementById('UserCoordinates');
if(UserPosition === null) {
DisplayElement.innerHTML = 'Waiting on GPS Position...';
} else {
DisplayElement.innerHTML =
'Current Position: ' + UserPosition.toUrlValue();
}
});
This will show the user their current position as it changes. If you are going to continue using a full screen map, you'll probably want to implement the UserCoordinates div as a map control. The API Reference has a good overview and multiple examples on this.
Display an info window when the user is within X meters of a location
This is a little tricky because there are multiple scenarios to handle and you don't want the infowindow opening repeatedly as they move within your radius.
Distance calculation
I see you have a distance function in your code, but I recommend using the one in the Spherical Geometry library of the API. You just have to specifically load the library with your api script tag:
<script type="text/javascript"
src="https://maps.googleapis.com/maps/api/js?libraries=geometry&sensor=true_or_false">
</script>
Then you need to add to the position_changed event handler:
var IsWithinRadius = false; //assume they start outside of the circle
var RadiusInMeters = 1000; //within 1 km
var LocationOfInterest = map.getCenter();
google.maps.event.addListener(GeoMarker, 'position_changed', function() {
var UserPosition = this.getPosition();
var DisplayElement = document.getElementById('UserCoordinates');
if(UserPosition === null) {
DisplayElement.innerHTML = 'Waiting on GPS Position...';
IsWithinRadius = false; //you don't know where they are
} else {
DisplayElement.innerHTML =
'Current Position: ' + UserPosition.toUrlValue();
var IsCurrentPositionInRadius =
Math.abs(google.maps.geometry.spherical.computeDistanceBetween(
UserPosition, LocationOfInterest)) <= RadiusInMeters;
var JustEnteredRadius = !IsWithinRadius && IsCurrentPositionInRadius;
IsWithinRadius = IsCurrentPositionInRadius;
if(JustEnteredRadius) {
//trigger action here.
alert("Within raidus");
}
}
});