3

I am trying to set map extent using an offset because there is a panel floating over the left side of the map and sometimes, when I zoom to a feature extent, the feature is partly hidden behind it.

I would like the extent to be always displayed and CENTERED in the map section that is not hidden by the panel

For instance the normal behavior is like below, but some of the feature is hidden behind the panel:

enter image description here

I would like to find a way to center the feature in the map section that is not hidden by the panel like the red rectangle below:

enter image description here

This is what I tried so far without success:

function zoomToExtent(extent) {
 var hiddenMapPartTopLeft = map.toMap(new ScreenPoint(0, 0)),
 hiddenMapPartBottomRight = map.toMap(new ScreenPoint(panel.position.left + panel.position.width, map.container.offsetHeight));
 var dx = new Extent({
 xmin: hiddenMapPartTopLeft.x,
 ymin: hiddenMapPartBottomRight.y,
 xmax: hiddenMapPartBottomRight.x,
 ymax: hiddenMapPartTopLeft.y,
 spatialReference: map.spatialReference
 }).getWidth();
 extent = extent.offset(dx, 0);
 map.setExtent(extent);
}

The map zoom way too far to the right.

Is there a solution for this?

Kirk Kuykendall
25.9k9 gold badges68 silver badges155 bronze badges
asked Dec 18, 2019 at 21:09
10
  • Confirming: this is the 4.x API? Commented Dec 19, 2019 at 14:01
  • Sorry, I should have mentionned its 3.x Commented Dec 19, 2019 at 23:16
  • Are the units of the map and panel the same? Commented Jan 6, 2020 at 20:45
  • The map units are in meters but the panel is in pixel Commented Jan 6, 2020 at 20:57
  • If you are using Web AppBuilder (I believe it is Launcpad theme). One of a workaround could be to hide/minimize the 'LayerList' widget(floating panel), when you zoom to a feature extent. If possible you can switch to 'Tab' theme - which has a separate tab for rendering the widgets without floating on map area. Commented Jan 7, 2020 at 11:38

2 Answers 2

1

You were almost there. Here is the correct code.

function zoomToExtent(extent) {
 var hiddenMapPartTopLeft = map.toMap(new ScreenPoint(0, 0)),
 hiddenMapPartBottomRight = map.toMap(new ScreenPoint(panel.position.width, map.container.offsetHeight)); // Removed panel.postion.left
 var dx = new Extent({
 xmin: hiddenMapPartTopLeft.x,
 ymin: hiddenMapPartBottomRight.y,
 xmax: hiddenMapPartBottomRight.x,
 ymax: hiddenMapPartTopLeft.y,
 spatialReference: map.spatialReference
 }).getWidth();
 extent = extent.offset(-dx, 0); //shift to right with -dx and to left with +dx
 map.setExtent(extent);
}

Also see the jsfiddle here. The shift the map after searching a location, click on My custom search box: and anywhere on jsfiddle window.

answered Jan 14, 2020 at 19:58
0

My approach would be different - not to set the extent - just recenter the map after zooming to the desired geometry.

I've created a little codePen based on the geolocate example, which creates a point and zoom to it, it also zooms in the start on Eiffel tower

I've changed the example so there will be side and bottom divs, as in your map.

After the geolocation and zooming:
- Create new definitions for 'centered' map width and height
- Center the map to the new position - all based on screen points - since the map is already focused on the desired geometry - we just need to move the map center according to the side and bottom divs.

Note: since the polygon can be hidden by the panels - I've added a setZoom to current zoom level minus 3 (can be 1 as well I guess).
GL!

EDIT: In order to activate the example - click on the locate button OR wait 2 seconds.. EDIT2: Basically I created a function that recenters the map when needed - like your zoomToExtent. It recenters the map according to the x,y of the current screen. You will also want to change the zoom level, depends on the polygon

function centerMap(zoom) {
 // Get dimensions of side div
 var sideDiv = document.getElementById('sideDiv'); 
 var centerdMapWidth = map.width - sideDiv.getBoundingClientRect().right;
 // Create centered screen X
 var centeredMapX = centerdMapWidth/2;
 // Get dimensions of bottom div
 var bottomDiv = document.getElementById('bottomDiv'); 
 var centerdMapHeight = bottomDiv.getBoundingClientRect().top;
 // Create centered screen Y
 var centeredMapY = map.height - centerdMapHeight/2;
 // Create new center point
 var scrPoint = new ScreenPoint(centeredMapX, centeredMapY); 
 // Create the center point in map units
 var centeredMapPoint = screenUtils.toMapPoint(map.extent, map.width, map.height, scrPoint);
 //Zoom out (to polygons...)
 map.setZoom(map.getZoom() - 3)
 // Move to the new center
 // Added a timeout to see the difference between the points
 map.centerAt(centeredMapPoint);
 document.getElementById('sideDiv').innerHTML = "New center: " + centeredMapPoint.x + "<br>" + centeredMapPoint.y;
}
answered Jan 7, 2020 at 11:24
2
  • Hi! thank you, but I am looking for a one shot function. Also, your codePen is not working. Commented Jan 7, 2020 at 20:41
  • 1
    It took me some time to re organize my answer. I hope it can help you. Commented Jan 7, 2020 at 22:48

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.