ThinkGeo.com    |     Documentation    |     Premium Support

How to find layers bounding box? and zoom map to that bounding box?

I have several layers from sql server tables. When I load them, I will apply some filters to load certain features, so not all features in the layer will be loaded into map.



I would like to know how to finding the bounding box of these found features?



Then when to zoom the map to that extent? Can I just tell the map the bounding box and then it will find the best scale?



Thanks,



Guangming

Hi Guangmin, 



I think that you can get an extent on the server, but you must invoke javascript “zoomToExtent” on the client as following statements: 



Server: 

[MapActionFilter] 

public string ZoomToExtent(Map map, GeoCollection args) 



string wkt = String.Empty; 

if (map != null) 



wkt = GetExtent(); 





return wkt; 





Client: 



<script language=“javascript” type=“text/javascript”>


   
function currentClick()


   
{


       
Map1.ajaxCallAction(‘Home’, ‘Index’, null, function (result)


       
{


           
var boundingBoxString =
result.get_responseData();


           
var wkt = new OpenLayers.Format.WKT();


           
var feature =
wkt.read(boundingBoxString);


           
Map1.getMapParser().map.zoomToExtent(feature);


       
});


   
}


</script>



Regards, 



Don

This is bad!



For this "simple" feature, how many client-server trips are needed for that to work?



I noticed that the desktop editor has a feature to zoom map to the extent of a layer.



we should have that too in core!


Hi Guangming,


The way on how to get the correct boundingbox depends on how
you display the features read from the SQL Server, if you load these features
using HighlightOverlay or EditOverlay or MarkerOverlay, I think
you can get its boundingBox  on client
directly, because both overlays render these features using SVG or HTML Canvas,
in other words, all these geometries are sent to the client, we can calculate
the boundingbox directly, while if we display these features using
LayerOverlay, I think the only option is taking way mentioned by DON, but I
think we can do some simplication here, but client-server ajax call is
required, you know the LayerOverlay will read these features and draw them on
server side, and then send the drawn tile images to client side to render them
as “” tag, in other words, it’s impossible for us to get these
features on client side.


Following are some hints on how to calculate the bounding
box of HighlightOverlay or EditOverlay or MarkerOverlay:


           
var layer = Map1.layers[2];

            var extent = layer.getExtent();

            Map1.getMapParser().map.zoomToExtent(extent);


 


Thanks,


Johnny



Why not doing this when you get the features and return both features and bounding boxes in a single call? 
  
 Jm.

Hi JM, 
  
 It depends, I think, if the layer is LayerOverlay, we need to a separate call, while for others, like the HighlightOverlay or EditOverlay or MarkerOverlay,we request them in a single call, but sometimes, we may don’t need the features, may bounding boxes is only required. 
  
 Thanks, 
 Johnny 
  


I found a way to do that in sql server side. You need to add a new CLR to do that in 2008 r2. MS already added such functions to 2012 version.

I think that is more efficient in my case: I know spatial features and need to find the bounding box/envelop of them.


Hi guangming, 
  
 Do you meant MS provide a function to calculate extent for layer in SQL server side?  
  
 Could you please share the function name and whether that solve your issue? 
  
 Regards, 
  
 Don

blogs.msdn.com/b/davidlean/archive/2008/10/27/sql-2008-spatial-samples-part-n-3-of-n-performance-improvement-methods.aspx



describes several workarounds for 2008 sql server; functions are OOB for 2012.



I recommended you guys add this bounding box filter into ur product: STIntersect should require more CPU!?

Hi Guangming,



Thanks for your investigation,but actually, I think we have supported the most of the such geography  functions in Core. I checked your question again, Not pretty sure, but I guess you are looking for:



Using NTS(by default):  extent = Feature.Union(selectedFeatures).GetBoundingBox();

Using SqlTypes: extent = (SqlTypesGeometryHelper.Union(selectedFeatures)).GetBoundingBox();



So, in controller side:



string extentString = string.Format(CultureInfo.InvariantCulture, "{0},{1},{2},{3}", extent.LowerLeftPoint.X, extent.LowerLeftPoint.Y, extent.UpperRightPoint.X, extent.UpperRightPoint.Y);

return extentString;



Client side:

function callback(result) {

        var extent = result.get_responseData();

        var bbox = new OpenLayers.Bounds(extent[0], extent[1], extent[2], extent[3]);

        Map1.zoomToExtent(bbox);

    }



If any thing I misunderstand, please feel free to correct me.

Regards,

Troy

Hi Guangming,



Thanks for your investigation,but actually, I think we have supported the most of the such geography  functions in Core. I checked your question again, Not pretty sure, but I guess you are looking for:



Using NTS(by default):  extent = Feature.Union(selectedFeatures).GetBoundingBox();
Using SqlTypes: extent = (SqlTypesGeometryHelper.Union(selectedFeatures)).GetBoundingBox();



So, in controller side:

string extentString = string.Format(CultureInfo.InvariantCulture, "{0},{1},{2},{3}", extent.LowerLeftPoint.X, extent.LowerLeftPoint.Y, extent.UpperRightPoint.X, extent.UpperRightPoint.Y);
return extentString;



Client side:
function callback(result) {
        var extent = result.get_responseData();
        var bbox = new OpenLayers.Bounds(extent[0], extent[1], extent[2], extent[3]);
        Map1.zoomToExtent(bbox);
    }



If any thing I misunderstand, please feel free to correct me.
Regards,
Troy

could you give the document links to the classes u referreed Feature, SQLGeometrySQLHelper?



I could not find them from the wiki pages.

Hi Guangming,



Please have a look on: wiki.thinkgeo.com/wiki/Think…etryHelper

As it comments, it is possible to be removed in next public release, but don’t worry it, we just want to figure out a better way to use it instead of a single helper class.



Hope it helps.

Regards,

Troy