Scalable google maps overlay - javascript

Is it possible to add an image overlay to a google map that scales as the user zooms?
My current code works like this:
var map = new GMap2(document.getElementById("gMap"));
var customIcon = new GIcon();
customIcon.iconSize = new GSize(100, 100);
customIcon.image = "/images/image.png";
map.addOverlay(new GMarker(new GLatLng(50, 50), { icon:customIcon }));
However, this adds an overlay that maintains the same size as the user zooms in and out (it is acts as a UI element like the sidebar zoom control).

There is a zoomend event, fired when the map reaches a new zoom level. The event handler receives the previous and the new zoom level as arguments.
http://code.google.com/apis/maps/documentation/reference.html#Events_GMap

You might want to check out openlayers
It's a very capable Javascript API - it supports a bunch of back ends, allowing you to transparently switch between, say, Google Map tiles and Yahoo Map tiles.

Well after messing around trying to scale it myself for a little bit I found a helper called EInserts which I'm going to check out.
Addition:
Okay EInserts is about the coolest thing ever.
It even has a method to allow you to drag the image and place it in development mode for easy lining up.

Related

Javascript OpenLayers before zoom event listener

I am trying to set up OpenLayers to not display the vector layer just before a zoom starts and make it reappear after a zoom ends. I have the zoom ends part already established like this:
map = new OpenLayers.Map('map_element', { eventListeners: { "zoomend": mapEvent}});
function mapEvent(event) {
if(event.type == "zoomend") {
hide_vector_layer();
}
}
But I don't see any kind of event listener for the start of a zoom in the documentation. There is a "movestart" which covers moving, panning, and zoom. Unfortunately, I can't use the "movestart" one, because I don't want the layer to disappear during a pan. You would think there would be a "zoomstart", as there is a "zoomend".
The reason I am trying to do this, is because I don't like how the vector layer zooms at a different rate when using Google Maps as a base layer. It looks wrong, looks like all the features are inaccurate, even though they land in the right place after the zoom is complete.
Any suggestions?
Here is a easy to add the 'BeforeZoom' event to the OpenLayers . Just add the code below to where you created your map object.
map.zoomToProxy = map.zoomTo;
map.zoomTo = function (zoom,xy){
//Your Before Zoom Actions
//If you want zoom to go through call
map.zoomToProxy(zoom,xy);
//else do nothing and map wont zoom
};
How this works:
For any kind of zooming activity, OpenLayers API ultimately calls the function called zoomTo. So before overriding it, we copy that function to a new function called 'zoomToProxy'. The we override it and add our conditional zoom logic. If we want the zoom to happen we just call new proxy function :)
For this purpose you should override moveTo and moveByPx methods of OpenLayers.Map for eliminate movestart event triggering for any actions except zooming.
I had the same problem that OP had, and I tried to solve it with drnextgis's solution. But unfortunately it didn't completely work:: the zoomChanged property in OpenLayers.Map.moveTo evaluates to true not only when the zoom level has changed, but also when the map has been resized.
My map was 100% of the user's browser window, so if they resized the window, the event would be triggered. This was undesirable for me, as I only wanted to trigger the event if the zoom level had actually changed. My solution was to create an new event, called "zoomstart", which I inserted at the top of OpenLayers.Map.moveTo. Here's the code:
var getZoom = this.getZoom();
if ( !!getZoom && !!zoom && this.isValidZoomLevel(zoom) && getZoom != zoom )
this.events.triggerEvent("zoomstart", zoom);
This code will pass the new zoom level to an event listener that is registered to zoomstart, and in my case I determine the map's restrictedExtent and do other stuff based upon the new zoom level.
Peace be with ye.
"movestart" handles "zoomstart". To detect if the zoomstart, try:
map.events.register("movestart",map, function(e) {
if(e.zoomChanged)
{
//zoom start code here
}
});
Solution of "Shaunak" is worked very well for me.
I want to restrict zooming below 11 so edited his code as
if (zoom > 11) {
map.zoomToProxy(zoom, xy);
}

How to listen for a layer zoom event in Polymaps?

I'm using Polymaps.js library for making maps.
It would be very useful to be able to observe zoom level changes on layers. I'm trying to keep a layer of points scaled by values in meters, so I need to recalculate the radii whenever the zoom level changes.
I'm using the on "move" function, which I think is triggered on zooms, too. There may be on on "zoom" function, too. I think that there is.
For example:
// whenever the map moves...
map.on("move", function() {
// get the current zoom
var z = map.zoom();
// show/hide parcels
parcels.visible(z >= 16);
});

how to create a padding around the edge of a google map

I have a very busy Google Maps app that I have built and I'm trying to create a "buffer zone" around the outside edge of the map so that the google map commands won't put things there. My solution was to create invisible divs and add them to the map as controls, one for each of the edges. This seems to work great as all of the google commands see them and adjust accordingly, and the map appears normally. For example, fitBounds ensures my bounds is not under the invisible layers. For the top where I have a control bar it's a perfect solution, but for the other edges where there is nothing, it creates a problem - I can't click on the map or info windows under these controls as they take the click event.
So I'm looking for one of 2 solutions:
1) can I make my invisible controls pass clicks through to the map, or;
2) is there a better way to pad the edge of the map; something that doesn't involve a much of math every time I want to call a fitBounds or panTo would be preferred as I automate a lot of map motion
Cheers
I managed to solve this.
The best way to add padding to your maps is with invisible controls. It creates the padding that all other map functions obey without any additional coding when call them. Here is how to do it for everyone else who needs this.
First.. I create a function to simplify creating the divs.
function createDummyDiv(w, h){
var out = $(document.createElement('div')).addClass('dummy-div').css('width', w).css('height', h);
return out[0];
}
Then I add the controls as needed. In this case I have the normal zoom control in the LEFT_CENTER position, so I had to create 2 for the left side. This creates a 10% padding on the left, right and bottom, and a 55px padding at the top under my own control bar.
map.controls[google.maps.ControlPosition.TOP_CENTER].push(createDummyDiv('100%', '55px'));
map.controls[google.maps.ControlPosition.LEFT_TOP].push(createDummyDiv('10%', '45%'));
map.controls[google.maps.ControlPosition.LEFT_BOTTOM].push(createDummyDiv('10%', '45%'));
map.controls[google.maps.ControlPosition.RIGHT_CENTER].push(createDummyDiv('10%', '100%'));
map.controls[google.maps.ControlPosition.BOTTOM_CENTER].push(createDummyDiv('100%', '10%'));
The.. the final fix to my problem is to put them behind the map layer with css.
.dummy-div{ z-index: -100 !important; }
I hope this helps someone else
Try to give the invisible DIV a negative z-index, e.g. -10
For me, fitBounds api worked itself with second parameter (padding)
Add padding to google map bounds

How to set default view in OpenLayers, WITHOUT restricting bounds?

Based on samples, I can see that you can set a default view in OpenLayers by saying something along the lines of:
var bounds = new OpenLayers.Bounds(-125, 25, -65, 50);
var map = new OpenLayers.Map('map', {restrictedExtent: bounds });
However, this also (as the name implies), restricts me to be able to ONLY navigate within these bounds. I can zoom out and see things outside of these bounds, but I can't then zoom back onto them, or scroll to them.
I've tried not having any restrictedExtent (or making it the entire map), but then I can't get it to focus on the area I want. I tried using:
map.setCenter(new OpenLayers.LonLat(0,0), 3);
console.log(map.getCenter());
To set the zoom and the center...but it doesn't seem to do ANYTHING, other than set the variable "center" which I can then read from map.getCenter() (if I don't set it, it's null, if I do set it, I can see it...but the map itself stays fully extended and it's center doesn't seem to change at all...)
The Map layer I am using is:
OpenLayers.Layer.OSM.Mapnik
with displayOutsideMaxExtent set to true... I'm really at a loss here.
My goal is to have a default region of the world zoomed in to and in view (such as the United States), with the option of viewers being able to go outside the default to view things.
I think I've figured it out. For whatever reason, the zoom was never changing, but the center apparently WAS moving (it was just so zoomed out I couldn't tell). Add to the fact that I needed to transform the center to use the google projection, and it seems to work just fine.
What I ended up doing was:
var lonlat = new OpenLayers.LonLat(20,37).transform(new OpenLayers.Projection("EPSG:4326"),new OpenLayers.Projection("EPSG:900913"));
map.setCenter(lonlat);
map.zoomTo(4);

How to override or remove a control in Google Map API

I was playing with Google maps for last two days and started understanding little bit about its functionality.
I was using Large Map i.e. 700 X 300 resolution map size and i was trying to implement controls used in small maps.
eg.
var map = new GMap2(document.getElementById("map_canvas"));
map.setCenter(new GLatLng(37.4419, -122.1419), 18);
map.setMapType(G_HYBRID_MAP);
**map.setUIToDefault();**
map.enableContinuousZoom();
var customUI = map.getDefaultUI();
customUI.controls.smallzoomcontrol3d=true; //1. trying to override largezoomcontrol3d
customUI.controls.menumaptypecontrol=true; //2. trying to override largezoomcontrol3d
map.setUI(customUI);
map.enableRotation(); //3. Enabling rotation
Here in 1(a). Small zoom control is not getting visible until i remove the line map.setUIToDefault() and add one more line customUI.controls.largezoomcontrol3d=false. Although I was expecting that by writing above code those control will get overridden.
1(b). I tried to use map.removeControl(Control:GControl) where i was not able to pass the correct parameter. I wanted to remove largezoomcontrol3d from map but i was not able to make out how to refer to this control in the current map.
Same overriding problem is occuring here also. The only difference here is that both the controls are visible here menumaptypecontrol and maptypecontrol, here menumaptypecontrol is overlapping on maptypecontrol
I am trying to enable rotation on map but it is not working for me.
thinking about map.removeControl you were quite closely to solution (if I got what you need). take a look here:
Controls
so, you need just use map.addControl function to add exactly what you need instead of what you did.
sorry, forgot about map rotation. I think the following simple example of Google Map can help you (I just never played with rotation, but example looks very simple to learnt from it):
Google Map rotation example

Categories