Hey, I just started using Google maps, and am having a problem. Adding overlays is working fine. If I add controls (zoom, left/right etc.), they are also working fine. But Googlemaps isn't allowing me to drag, even if I set map.enableDragging(). It also won't respond to any of my GEvent.addListeners. I've looked on other sites, and there's supposed to be a hand icon on mouseover to drag and click and such, and all I have is my pointer. Am I doing something wrong? Parts of my code:
The declaration of the map. EnableDragging is supposed to be default, and it's not even working when I call the function to set it to true.
Boozemap.map = new GMap2( $('#map_mapholder').get(0));
Boozemap.map.enableDragging();
The function to add a marker, which makes the marker show up, but not be interactive:
Boozemap.addBCMarker = function(lat, lng)
{
var point = new GLatLng(lat, lng);
var icon = new GIcon();
icon.image = absoluteFilepath("images/fstar.png");
icon.iconSize = new GSize(25, 25);
icon.iconAnchor = new GPoint(140, 25);
var bcmarker = new GMarker(point, icon);
GEvent.addListener(bcmarker, 'click', function(){alert('clicked!')});
Boozemap.map.addOverlay(bcmarker);
}
Any and all help would be lovely, thanks!
I figured it out, but it's kind of weird. The majority of my map was indeed getting covered, but it was getting covered by the copyright div that's built into the google API. I'm pretty sure I can fix it through CSS, but it seems strange that google would mess up like that, so I'm assuming I did something wrong. Is there a google maps API CSS that I'm supposed to include, or something?
Thanks to all those who helped.
Related
I'm using the ng-map directive to display a map. The map has markers that show an infowindow whenever there's a mouseover on the marker. Sometimes however, the infowindow doesn't appear.
Other than this, I haven't been able to identify any pattern to what's happening, as the problem occurs for a different marker each time. I'm outputting data to the infowindow however the issue doesn't seem to be 'data related' as all data for the selected location seems to be correct at the point where the issue occurs.
I have a showInfo method that is being called on a mouseover like this:
showInfo(event, loc, infoWindowTemplate, map, mapsController) {
loc - data for the clicked location
infoWindowTemplate - the info window template to use (this is always the same for a particular map, however this is configurable, so if I'm showing a map for mobile, I use one infowindow template, if I'm showing a desktop map, I use a different one)
map - a reference to the NgMap object on the controller
mapsController - the controller itself (I strongly suspect that this is a bad code smell - it was the easiest way I could figure out to get reference back to the controller following the mouseover)
Here is the body of the method:
map.getMap(mapsController.mapId).then(function (myMap) {
var selectedMarker = myMap.markers["L: " + loc.position[0] + ", " + loc.position[1]];
selectedMarker.locationInfo = loc;
console.log("about to show infowindow - infoWindowTemplate = " + infoWindowTemplate);
// console output = "cached-myTemplate.html"
myMap.showInfoWindow(infoWindowTemplate, selectedMarker);
selectedMarker is definitely referring to the correct marker object. My template looks like this:
<script id="cached-myTemplate.html" type="text/ng-template">
<a class="map-location__link" href="/locations/{{anchor.locationInfo.locationId}}" target="_blank">
<img src="{{anchor.locationInfo.locationImageThumbnail}}" />
</a>
</script>
The issue seems to be that calling 'showInfoWindow' is intermittently failing somehow (although there are no errors in the console). Any comments or answers with ideas of what may be causing the issue or what else I can do to diagnose it will be appreciated!
I discovered that this is a timing issue. Delaying the 'turn' in which showInfoWindow is called (by adding a short timeout) fixed the issue:
map.getMap(mapsController.mapId).then(function (myMap) {
....
this.$timeout(function () {
dealmap.showInfoWindow(infoWindowTemplate, selectedMarker);
}, 100)
}.bind(this));
I am working on a leaflet application and would like to mimic the default draw control panel buttons to move them to a more convient location on my application. The icons in question being these
I can see the objects within the drawcontrol I just don't know how to invoke these methods
Thanks so much
I found the solution, the primary call looks like so
this.polyline.enable(); for the draw functions, meaning that marker would look like
this.marker.enable();
defined as
this.polyline = new L.Draw.Polyline(this.map, { shapeOptions: { color: 'green' } });
this.marker = new L.Draw.Marker(this.map, {icon: new mark()});
same goes with the other polys to add to the map, zoom-in/out is also this.map.zoomIn; this.map.zoomOut respectively
My aim is to create a map for my work in OpenLayers 3 with several layers. One takes a basic feed from OpenStreetMaps. Another will be a transparent layer showing outlines of regions (not done yet). The third one, which is the one I'm having trouble with, shows a series of icons representing indivudal sites of interest on the map. I load the sites from a JS data stucture included as a separate script file. I have managed to get my code to add features that appear at the correct lat/lon. My next step is to get a HTML box (div) to appear in front of the map when they click on an icon (to display details of the site). However, I cannot get this to work. Apologies for my noobish coding, but it's really got me stumped and I'd really appreciate any help.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="ol.css" type="text/css">
<link rel="stylesheet" href="map.css" type="text/css">
<script src="ol.js" type="text/javascript"></script>
<script src="sites.js" type="text/javascript"></script>
<script type="text/javascript">
function buildLayerFromSites(allSites)
// allSites is just an array of data structures
{
var count, site;
// for each site in the array, make a feature
for (count=0;count<allSites.length;count++)
{
geom = new ol.geom.Point(ol.proj.fromLonLat([allSites[count].longitude,allSites[count].latitude]));
site = new ol.Feature(geom);
site.Name = allSites[count].siteName; // <-- can I assign further details in the structure like this?
var siteStyle = new ol.style.Style({
image: new ol.style.Icon ({
src: 'icon-blue.png',
scale: 0.1,
opacity: 0.9,
})
})
site.setStyle(siteStyle);
siteFeatures[count] = site;
}
siteSource = new ol.source.Vector ({
features: siteFeatures
})
siteLayer = new ol.layer.Vector({
source: siteSource
});
map.addLayer(siteLayer);
}
</script>
<title>Map</title>
</head><body>
...
<div id="map" class="map">
...
<script type="text/javascript">
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
view: new ol.View({
center: ol.proj.fromLonLat([115.51, -31.57]),
zoom: 8
})
});
buildLayerFromSites(includeSites); // adds the second layer with the sites
// click event handler, basically same as http://openlayers.org/en/v3.12.1/examples/icon.html
map.on('click', function(evt) {
var feature = map.forEachFeatureAtPixel(evt.pixel,
function(feature,layer) {
return feature;
});
if (feature) {
console.log("feature got clicked on"); // do stuff
} else {
console.log("didn't click a feature");
}
});
</script>
</body>
</html>
The map and the icons load, but when I click the icons, no matter how zoomed in or out I am, it doesn't detect a match with the icon I'm clicking on. The thing is, the event handler code is the same as in the official example, which make me think it's the way I'm creating the features. On the other hand, the features display fine as icons, its just the click event that doesn't seem to work. Similar weird stuff happens for the mouse cursor change from the example. I sorta guess it's because I don't understand the way the data/functions are structured in OL, and I find the documentation doesn't fully explain how it all works, so I've been writing snippets like this trying to take a look:
var myLayers = map.getLayers();
console.log("keys - " + myLayers.getKeys); // prints out 'function (){return Object.keys(this.B)}' - what does that mean?
var mySource = myLayers.getSource;
console.log("source" + mySource.getProjection); // doesn't work
var features = mySource.getFeatures; // says mySource is undefined
Of course it fails totally.
How do I get it to detect the clicks on the icons/features so I can tell a div to appear and display my data at the right time? Am I doing this right? What don't I understand about the way the data/functions work? I'm a big JS noob so I hope I'm not doing something stupid, but it's causing me massive problems and I could really use your help! Thanks all!
If someone else comes upon this issue: my solution was changing the Feature icon PNG image to not have transparency (no color).
If your image is PNG and has transparency,
where it is transparent it won't be clickable
(I'm on OpenLayers v5). For example, I had an image that was a circle and it was transparent inside and just colored on the outside border.
When I changed the image to something without transparency in the middle (it can still be PNG of course) everything was okay. It seems this is how OpenLayers handles pixels for images - if the map can be seen through the image, it's not a 'hover' even though you are on a Feature.
console.log("keys - " + myLayers.getKeys); // prints out 'function (){return Object.keys(this.B)}' - what does that mean?
It means you're trying to print the function itself, not the result of it's execution. Should be
console.log("keys - " + myLayers.getKeys())
Same with
mySource.getProjection();
mySource.getFeatures();
Usually if the attribute name starts with "get" and is written in camelCase - it's a function. Keep that hint in mind :)
After long hours staring at my screen and hitting my head on my desk, I've stumbled across the solution to my problem. It's a little obscure but mind-numbingly simple/stupid/silly. I thought I'd post the solution here for others.
I wrote a couple of lines of code to resize the viewport when the page is loading and again when the window is resized, so the map would adjust to the available user's browser window space. Unfortunately, as far as I can work out, OL doesn't know about it so the icons and the features are no longer in the same place after the resize. I didn't know this though, until after countless hours I was randomly clicking and resizing it detected a feature click.
Luckily there is an easy way to solve it once you figure out this is the problem. Basically just add map.updateSize() to the part of your code that resizes the viewport. So far this seems to have solved the problem.
The functions is only work on pixel of features so to solve this you can add some style with your image with fill with something like rgb(255,0,0,0.001) propert. I have tried it and i worked for me.
I am developing an application which uses google maps api v3 to show markers and infowindows.
Well, I have N markers stored within an array and a global infowindow used to show some information.
The infowindow contents are shown simply by clicking a marker, created in this way:
/* global js stuff */
var g_map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
var g_current_popup = new google.maps.InfoWindow({ content: "" });
var g_markers = [];
/* create marker function */
function addMarker(p_infowindow_contents)
{
var l_marker = new google.maps.Marker( all the stuff needed );
google.maps.event.addListener(l_marker, 'click', function()
{
g_current_popup.close(); // if already open, it must be closed and reloaded
g_current_popup.setContent(p_infowindow_contents);
g_current_popup.open(g_map, l_marker);
});
g_markers.push(l_marker);
}
Everything works as expected, except for a little graphical glitch: when the infowindow is appearing, I see the infowindow 'tip' positioned at an unknown location for a tenth of a second, then it disappears and I see the correct infowindow.
Look at this screenshot took just before the tip disappears:
Does anyone experienced something like this?
Could it be some CSS issue?
Thanks
It does not look like this is a problem with your code, I think it more likely a browser issue. I was able to validate the same thing looking at the infowindow example that Google provides in Firefox, but not in Chrome:
https://developers.google.com/maps/documentation/javascript/examples/infowindow-simple
it seems to happen more visibly when the map has to scroll to fit the infowindow, but I would say that it is not a requirement for it to do so. It is likely just an artifact with the screen taking a few clock cycles to catch up with the DOM.
I'm relativ new to the Google Maps API.
My situation: Website with an fullscreen Google map as background.
First problem: If the user scrolls down, or zooms out too much, there is an gray background. Is it possible to limit the max zoom-out, and that he can't scroll out? Or maybe repeat the map vertical (with markers).
If it's possible to set the max zoom-out and lock him within the map, how could I dynamically calculate the max zoom-out releated to the screen-resolution?
Second problem: Is it possible to add custom javascript to a marker?
Example: I create 5 markers, each one should hold an custom value (ID from the database). On click my own function should be called with the custom value as parameter and do some stuff.
Edit: This is what I mean with grey: (vertical "end" of google maps)
Map object have propert maxZoom, set it when map created
yes it is possible, you can add click events, change popups open, and since it is javascript you can add any additional data just as simple as markr.MyData = 'something interesting'
I am not sure what gray part you mean? I can't see gray parts with max and min zoom in google maps
Okay. Got it finally working! :)
Fixing grey area (handles also zooming):
function setBounds() {
google_allowedBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(-85.000, -122.591),
new google.maps.LatLng(85.000, -122.333));
google_lastCenter = google_map.getCenter();
google_lastZoom = google_map.getZoom();
google.maps.event.addListener(google_map, "bounds_changed", function () {
checkBounds();
});
google.maps.event.addListener(google_map, 'center_changed', function () {
checkBounds();
});
}
function checkBounds() {
if (google_allowedBounds.getNorthEast().lat() > google_map.getBounds().getNorthEast().lat()) {
if(google_allowedBounds.getSouthWest().lat() < google_map.getBounds().getSouthWest().lat()) {
google_lastCenter = google_map.getCenter();
google_lastZoom = google_map.getZoom();
return true;
}
}
google_map.panTo(google_lastCenter);
google_map.setZoom(google_lastZoom);
return false;
}
Marker click handler:
google_listener = google.maps.event.addListener(marker, 'click', markerHandler);
function markerHandler(event) {
window.console.log(this);
}