In a given instance of google maps...
Is there a way to turn off the other instances of the maps which tile to the right and left of the initial central map?
I've seen ways to restrict the pan ability of the map ... but it uses lat + lng to determine when to re-center the map ... and thus the usage falls apart at different zoom levels.
For example: https://google-developers.appspot.com/maps/documentation/javascript/examples/map-simple
If on zooms all the way out, you can see how the map of the globe is tiled along the x-axis.
I would like a single instance of the map.
You could add an observer to the zoom_changed event, and set the minZoom if more than 90 degrees of map is shown. The second statement recursively reduces the zoom to an acceptable limit before the limit is known.
var zoomObserver = function () {
width = Math.abs(map.getBounds().getNorthEast().lat() -
map.getBounds().getSouthWest().lat());
if (width > 90){
var opt = { minZoom: map.getZoom()};
map.setOptions(opt);
}
if (width > 179){
map.setZoom(map.getZoom() + 1);
}
};
google.maps.event.addListener(map,'zoom_changed', zoomObserver );
This simple solution works for most use cases, doesn't take into account doubling the width of the map through resizing the browser window, so you may need to add the observer to another event in that case.
Related
I am attempting to zoom into a clicked shape or group of shapes. The actual move works, but the property to tell it to animate does not.
map.getViewModel().setLookAtData({
bounds: boundingBox
}, true);
This does move and zoom correctly but without animation. If I add a specific zoom level it animates as expected, but part of what I need it to figure out is the zoom level for me.
I can probably fake it if I can work out any reliable way to calculate what the zoom level should be manually, but that is less than ideal. For what ever reason, using only bounds breaks the feature that allows animation. Any work around for this?
Map instance methods such as setZoom(), setCenter() and setViewBounds() accept a second argument indicating whether an animated transition should be applied.
We recommend not to create your own zoom animations as shown in the snippet below:
// Assumption: 'map' is initialized and available.
var currentZoom = map.getZoom();
var endZoom = currentZoom + 3;
// Update zoom level on each animation frame,
// till we reach endZoom:
function step() {
currentZoom += 0.05;
map.setZoom(currentZoom);
(currentZoom < endZoom) && requestAnimationFrame(step);
}
// Start zoom animation
step();
Instead, call the method setZoom() with an optional second parameter to perform an animation:
/** * Assumption: 'map' is initialized and available */ // Call
getZoom() with an optional second parameter, // indicating that an
animation is to be performed: map.setZoom(map.getZoom() + 3, true);
Possible Workaround: seems to work if you pass the bounds centroid:
let data = {bounds: bounds, position: bounds.getCenter() };
map.getViewModel().setLookAtData(data, opt_animate);
I use openlayers3 to build an application
I would like to change the zoomlevel icons are visible at
https://bestofosm.org/?lon=4.0798&lat=50.9136&zoom=15#interesting-het-loo-garden
for example
if you go to London you see airports are visible at zoomlevel 10
lets say I want all touristic icons visible at zoomlevel 10
and airport icons at zoomlevel 15
is this possible?
The most simple solution is to put your markers in different layers and give each layer a minResolution and maxResolution. When the map zooms outside these resolutions the layers will automatically become hidden. Something like:
var touristicIcons = new ol.layer.Vector({
source: touristicIconsSource,
minResolution: xx
maxResolution: xx
});
// Repeat for airports layer, with different resolutions
Writing down a zoom level as a resolution will not work. You will need to find out what resolution belongs to your desired zoom level. The easiest way to do this is with this little hack, that logs the zoom level and resolution every time you scroll through the map:
map.getView().on('change:resolution', function (event) {
var view = event.currentTarget;
console.log('Zoom: ' + view.getZoom() +
', resolution: ' + view.getResolution());
});
In OpenLayers 2D maps there's a property called restricted extent that doesn't allow to pan or zoom outside a defined bounding box.
Can I make something similar with Google Earth Plugin in 3D?
Obviously the problem is that one can bend (incline) the view, something that cant be achieved in 2D.
I have already restricted the view if thers no bend or incline in the map but that's far from being what I want..
Thanks!!
Update 1:
By now I have restricted the bbox with a handler on viewchangeend event, if the actual viewport (north, south, east, west) is outside some predefined initial values I move the view to the initial position again.
var viewchangeend = function viewchangeendhandler(){
var actualViewport = {
north: ge.getView().getViewportGlobeBounds().getNorth(),
south: ge.getView().getViewportGlobeBounds().getSouth(),
east: ge.getView().getViewportGlobeBounds().getEast(),
west: ge.getView().getViewportGlobeBounds().getWest()
};
if (actualViewport.north > initialViewport.north || actualViewport.south < initialViewport.south ||
actualViewport.east > initialViewport.east || actualViewport.west < initialViewport.west){
var la = ge.createLookAt('');
la.set(initialX, initialY, 0, ge.ALTITUDE_RELATIVE_TO_GROUND, 0 , 0, 50000);
ge.getView().setAbstractView(la);
}
}
For example in the initial case where I dont incline the view the relation north-south (north minus south) is static, but when I incline the view the relation grows and the initial viewport cannot be used to know if the actual viewport is ok.
Thanks again!
Perhaps you should consider using hitTest() instead of getViewportGlobeBounds()
See this SO Question which links to this Google Example
Have a play with the Google Example by tilting the view and see the resulting difference between the two
The Flex Canvas container is limited to 10,000x10,000 pixels. Yet, I've seen Flex apps that are scrolling way more than 10,000 pixels. Any idea how this can be done?
The content I want to scroll is in pieces already, but I need to add those pieces to something that can scroll vertically more than 10,000 pixels.
Depending on what you actually want to display you may be able to split your content into tiles. This is how Google Maps works, every time the map is moved the program determines which tiles are visible on the screen and loads them in. Any markers or overlays that are on the map are notified that the map has moved and determine where their new location is. If their location is off the screen they can be removed from the canvas. For example, the width of all the tiles at zoom level 20 on Google Maps is (256 pixels * 2^20) which equals 268,435,456 total pixels.
Essentially you just need to create a special Sprite that keeps track of the actual x,y location it is supposed to be positioned at. Any time the container moves you simply iterate through all of the child objects and determine where to put them.
function onCanvasScroll() {
//determine the top left coordinates of the canvas
//you will figure out how to do this depending on how the scrolling window
//is implemented
var canvas_scroll_x;
var canvas_scroll_y;
//create a bounding box for the canvas
var view_bounds = new Rectangle(canvas_scroll_x, canvas_scroll_y, canvas.width, canvas.height);
for (child in canvas) {
var x = child.actual_x - view_bounds.x;
var y = child.actual_y - view_bounds.y;
var childBounds = new Rectangle(x, y, child.width, child.height);
//determine if the component is visible on screen
if (view_bounds.intersects(child_bounds)) {
child.visible = true;
child.x = x;
child.y = y;
}
else {
child.visible = false;
}
}
}
So if you have a canvas that is positioned at (100, 20000), a sprite that is positioned at (300, 20100), and a window that is (640,408), you would place it at (200, 100) and it would be visible on the screen.
Instead of just setting visible to true or false a better approach would be to remove the items from the canvas entirely when they are not within the bounds of the view.
Pardon my noobishness, but, although I've seen this issue discussed, I haven't found an answer. I am trying to draw concentric circles on a Google Map using the API v3, making each clickable as on a bullseye target, but always the largest one ends up on top, which means it is the only clickable one.
The following uses an array called "subjects" that consists of increasing radii and various fillcolors.
for (i=0;i<subjects.length;i++) {
radi = subjects[i][0];
fillcolr = subjects[i][1];
zindx = subjects.length - i;
newcircle = new google.maps.Circle({
radius: radi,
center: centerPoint,
strokeWidth: 1,
fillOpacity: 1.0,
fillColor: fillcolr,
zIndex: zindx
});
// display it
newcircle.setMap(map);
// make outer circle clickable
google.maps.event.addListener(newcircle, 'click', function() {
circleClickedInfo(i);
});
The circles are there, the zIndex is set, but the biggest circle is always on top. I have tried setting zIndex on a pass afterwards, boosting each zIndex by 10000, reversing the order in which I create the circles, not setting the zIndex explicitly, etc. I'm sure I am missing something obvious (see the aforementioned noobishness), but I can't figure out what it is. TIA for any pointers...
Try this for every shape you need:
selectedShape.setOptions({zIndex:0});