11
Jun
13

Autodesk Infrastructure Map Server – Auto-Zoom On Load

Whether you are using AIMS 2014 or MapGuide OpenSource 2.5, there is a way to automatically zoom and highlight objects.

I will do this demo using FUSION or Flexible Web Layouts.

We want to be able to pass parameters to the template like the following.

http://localhost/mapserver2014/fusion/templates/mapguide/slate/index.html?LAYERNAME=Roads&KEYNAME=ID&KEY=644,684&ISSTRING=1

The parameters are:

  • LAYERNAME
  • KEYNAME
  • KEY
  • ISSTRING

The LAYERNAME is the layer name in the map (i.e. Roads)
The KEYNAME is the column you want to search by (i.e. ID)
The KEY is the comma delimited list of matches (i.e. 644,684)
The ISSTRING flag tells whether the KEYNAME is String or Number.

I am using the SLATE template in MapGuide/AIMS, found in C:\Program Files\Autodesk\Autodesk Infrastructure Web Server Extension 2014\www\fusion\templates\mapguide\slate\index.html

To start the process, we need to trigger a javascript function once the map is loaded, around line 174, add a call to a function called zoomToObject()

var initPanelHandler = function() {
zoomToObject();
if(isTaskPaneRegistered) return;

Next create a zoomToObject() function that will pass all the parameters to a PHP Page to get the selectionXML, (paste this above the var showOverviewMap = function() { line):

function zoomToObject()
{
var mapWidget = Fusion.getMapById('Map');
var SESSION =mapWidget.aMaps[0].getSessionID();
var MAPNAME = mapWidget.aMaps[0].getMapName();

var KEY=getParam('KEY');
var ISSTRING=getParam('ISSTRING');
var KEYNAME=getParam('KEYNAME');
var LAYERNAME=getParam('LAYERNAME');

//The GETSELECTIONXML.php returns the XML of selected features.
var AJAXURL = "/mapserver2014/GETSELECTIONXML.php?MAPNAME=" + MAPNAME;
AJAXURL = AJAXURL + "&SESSION=" + SESSION;
AJAXURL = AJAXURL + "&KEYNAME=" + KEYNAME;
AJAXURL = AJAXURL + "&LAYERNAME=" + LAYERNAME;
AJAXURL = AJAXURL + "&KEY=" + KEY;
AJAXURL = AJAXURL + "&ISSTRING=" + ISSTRING;

var xmlhttp;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
mapWidget.setSelection(xmlhttp.responseText, true);
}
}
xmlhttp.open("GET",AJAXURL,true);
xmlhttp.send();

}

we also need the getParam() function to harvest the parameters sent to the page:


function getParam(sname)
{
var params = location.search.substr(location.search.indexOf("?")+1);
var sval = "";
params = params.split("&");
// split param and value into individual pieces
for (var i=0; i<params.length; i++)
{
temp = params[i].split("=");
if ( [temp[0]] == sname ) { sval = temp[1]; }
}
return sval;
}

Finally, the GETSELECTIONXML.php (I put this in the www folder of C:\Program Files\Autodesk\Autodesk Infrastructure Web Server Extension 2014\www\)

<?php

$configFilePath = "C:\Program Files\Autodesk\Autodesk Infrastructure Web Server Extension 2014\www\webconfig.ini";

$session = urldecode($_REQUEST["SESSION"]);
$mapName = urldecode($_REQUEST["MAPNAME"]);

$keyName = urldecode(stripslashes($_REQUEST["KEYNAME"]));
$layerName = urldecode(stripslashes($_REQUEST["LAYERNAME"]));
$isString = urldecode(stripslashes($_REQUEST["ISSTRING"]));

$key = urldecode(stripslashes($_REQUEST["KEY"]));

if($isString == true)
{
$key = $key . ',0';
$key = str_replace(",", "','", $key);
$key = "'" . $key . "'";
}

try

{
MgInitializeWebTier($configFilePath);

$userInfo = new MgUserInformation($session);

$siteConnection = new MgSiteConnection();

$siteConnection->Open($userInfo);

$featureService = $siteConnection->CreateService(2);

$resourceService = $siteConnection->CreateService(0);

$map = new MgMap($siteConnection);

$map->Open($mapName);

$queryOptions = new MgFeatureQueryOptions();

$queryOptions->SetFilter($keyName . " in (" . $key . ")");

$layer = $map->GetLayers()->GetItem($layerName);

$parcelDataResId = new MgResourceIdentifier($layer->GetFeatureSourceId());
$featureClassName = $layer->GetFeatureClassName();

$featureReader = $featureService->SelectFeatures($parcelDataResId, $featureClassName, $queryOptions);

$selection = new MgSelection($map);

$selection->AddFeatures($layer, $featureReader, 0);

$selectionXml = $selection->ToXml();

$selection->Save($resourceService, $map->GetName());

//dump the XML out to a JAVASCRIPT variable

echo $selectionXml;

}

catch (MgException $e)
{

echo $e->GetMessage();

echo $e->GetDetails();

}

?>


That’s it.  It will work with the sample data that comes with MapGuide and AIMS, Sheboygan, or with any map you wish.

This will work with any FUSION application (flexible web layout),  on any version of mapguide.  The only thing you have to change is this line:

$configFilePath = “C:\Program Files\Autodesk\Autodesk Infrastructure Web Server Extension 2014\www\webconfig.ini”;

Just point it to the correct www folder.

ZOOMTOOBJECT_MAPGUIDE

Advertisements

44 Responses to “Autodesk Infrastructure Map Server – Auto-Zoom On Load”


  1. June 12, 2013 at 1:50 pm

    &KEY should have two IDs in there in this example: KEY=644,684

    That way it selects both items. If the KEY=644 it would only select a single Road with an (ID=644)

  2. 3 Kajar
    June 13, 2013 at 6:31 am

    But how final URl looks like, is it like I describet in previous post. I just cant this working.
    Do I have to add map name and location in index.html: MAPNAME= Library://Map.MapDefinition
    and code:
    var AJAXURL = “/mapserver2014/GETSELECTIONXML.php?MAPNAME=Library://Map.MapDefinition” + MAPNAME;

    In index.html file can I just copy all code from you post after: if(isTaskPaneRegistered) return;

    My code after row 173 is:

    var initPanelHandler = function() {
    zoomToObject();
    if(isTaskPaneRegistered) return;
    function zoomToObject()
    {
    var mapWidget = Fusion.getMapById(‘Map’);
    var SESSION =mapWidget.aMaps[0].getSessionID();
    var MAPNAME = mapWidget.aMaps[0].getMapName();

    var KEY=getParam(‘KEY’);
    var ISSTRING=getParam(‘ISSTRING’);
    var KEYNAME=getParam(‘KEYNAME’);
    var LAYERNAME=getParam(‘LAYERNAME’);

    //The GETSELECTIONXML.php returns the XML of selected features.
    var AJAXURL = “/mapguide/GETSELECTIONXML.php?MAPNAME=” + MAPNAME;
    AJAXURL = AJAXURL + “&SESSION=” + SESSION;
    AJAXURL = AJAXURL + “&KEYNAME=” + KEYNAME;
    AJAXURL = AJAXURL + “&LAYERNAME=” + LAYERNAME;
    AJAXURL = AJAXURL + “&KEY=” + KEY;
    AJAXURL = AJAXURL + “&ISSTRING=” + ISSTRING;

    var xmlhttp;
    if (window.XMLHttpRequest)
    {// code for IE7+, Firefox, Chrome, Opera, Safari
    xmlhttp=new XMLHttpRequest();
    }
    else
    {// code for IE6, IE5
    xmlhttp=new ActiveXObject(“Microsoft.XMLHTTP”);
    }
    xmlhttp.onreadystatechange=function()
    {
    if (xmlhttp.readyState==4 && xmlhttp.status==200)
    {
    mapWidget.setSelection(xmlhttp.responseText, true);
    }
    }
    xmlhttp.open(“GET”,AJAXURL,true);
    xmlhttp.send();

    }

    //we also need the getParam() function to harvest the parameters sent to the page:

    function getParam(sname)
    {
    var params = location.search.substr(location.search.indexOf(“?”)+1);
    var sval = “”;
    params = params.split(“&”);
    // split param and value into individual pieces
    for (var i=0; i<params.length; i++)
    {
    temp = params[i].split(“=”);
    if ( [temp[0]] == sname ) { sval = temp[1]; }
    }
    return sval;
    }
    //register this with MAP_LOADED so that the initial layout will remain
    Fusion.registerForEvent(Fusion.Event.TASK_PANE_LOADED, showTaskPane);
    isTaskPaneRegistered = true;

  3. June 13, 2013 at 2:30 pm

    http://localhost/mapserver2014/fusion/templates/mapguide/slate/index.html?ApplicationDefinition=Library%3a%2f%2fSamples%2fSheboygan%2fLayouts%2fslate.ApplicationDefinition
    &LAYERNAME=Parcels
    &KEYNAME=ID
    &KEY=630813
    &ISSTRING=true
    works for me.

    Just remember, the two functions should be stand alone. Paste them at the bottom of the index page (just above the tag).

  4. 6 Kajar
    June 14, 2013 at 7:19 am

    I put both functions at the bottom of the index page just above but still not working, really dont know what I doing wrong. I’m using opensource Mapguide 2,5 version.
    Can you past here your index.html full code.

  5. June 14, 2013 at 11:04 am

    It may be your GETSELECTIONXML.php , did you change the Webconfig path?

  6. 8 Kajar
    June 14, 2013 at 12:16 pm

    My webconfig.ini file is in www folder and in GETSELECTIONXML.php I have $configFilePath = “C:\Program Files\OSGeo\MapGuide\Web\www\webconfig.ini”;
    so its seems correct.

  7. June 14, 2013 at 3:11 pm

    Remember when copying from WordPress. Your Quotes may get assigned left and right, you may have to put them back to up and down.

    Also, in the GETSELECTIONXML.php, you may want to swap the double quotes with single quotes:

    From:

    $key = $key . “,0”;

    To:

    $key = $key . ‘,0’;

    also, make sure that in the index.htm for slate, that you have
    var AJAXURL = “/mapguide/GETSELECTIONXML.php?MAPNAME=” + MAPNAME;

    instead of:
    var AJAXURL = “/mapserver2014/GETSELECTIONXML.php?MAPNAME=” + MAPNAME;

  8. 10 Kajar
    June 16, 2013 at 12:19 pm

    Thanks Gordon, i got this working. Problem was php, I had emty fist row in php file.

  9. 11 Kajar
    July 3, 2013 at 1:14 pm

    If I want just to use this zoomto object function without selecting object when map is loading.
    Can you suggest me how to change this php or code in index.html.

  10. April 1, 2014 at 7:03 pm

    I have the javascript working I put some alerts in the code to see, but I get no results on selecting the key from the url. I copied all code from this page and did what you said and nada. using AIMS 2014 with a .net install.

  11. April 1, 2014 at 7:21 pm

    Befor the mapWidget.setSelection(xmlhttp.responseText, true); line alert the responseText to see if you are selecting objects:

    alert(xmlhttp.responseText);

    If you get back an XML without and in there, your query might be incorrect….

  12. April 1, 2014 at 7:34 pm

    no alert popping up??
    var xmlhttp;
    if (window.XMLHttpRequest)
    {// code for IE7+, Firefox, Chrome, Opera, Safari
    xmlhttp=new XMLHttpRequest();
    }
    else
    {// code for IE6, IE5
    xmlhttp=new ActiveXObject(“Microsoft.XMLHTTP”);
    }
    xmlhttp.onreadystatechange=function()
    {
    if (xmlhttp.readyState==4 && xmlhttp.status==200)
    {
    alert(xmlhttp.responseText);
    mapWidget.setSelection(xmlhttp.responseText, true);
    }
    }
    xmlhttp.open(“GET”,AJAXURL,true);
    xmlhttp.send();

    }

  13. April 1, 2014 at 7:39 pm

    How about after the:
    xmlhttp.open(“GET”,AJAXURL,true);

    use:

    window.open(AJAXURL);

    to view what is being sent and returned…

  14. April 1, 2014 at 7:43 pm

    I get The webpage cannot be found
    sorry iam moving up from mapguide 6.3 so I am lost I have all coding in aspx,javascript and vb.net… learned as I went

  15. April 1, 2014 at 7:46 pm

    aaa I changed the var AJAXURL = “/mapserver2014//GETSELECTIONXML.php?MAPNAME=” + MAPNAME;
    to var AJAXURL = “/mapserver2014/www/GETSELECTIONXML.php?MAPNAME=” + MAPNAME;

    and got

    An exception occurred in FDO component. Error occurred in Feature Source (Library://Data/parcels.FeatureSource): String does not represent a valid filter. (Cause: String incorrectly formatted. , Root Cause: String incorrectly formatted. )

  16. April 1, 2014 at 7:46 pm

    So the AJAXURL is incorrect….it assumes you are using AIMS 2014, if not, you will have to change your code from:

    var AJAXURL = “/mapserver2014/GETSELECTIONXML.php?MAPNAME=” + MAPNAME;

    to

    var AJAXURL = “/mapguide/GETSELECTIONXML.php?MAPNAME=” + MAPNAME;

    or wherever you put the GETSELECTIONXML.php page……

  17. April 1, 2014 at 7:55 pm

    Also, you may watch the URL. Is the key a Numeric or a String? the URL Parameter asks?
    &ISSTRING=1 – which is true
    – if it is numeric then
    &ISSTRING=0

  18. April 1, 2014 at 7:57 pm

    this is what I was trying
    it come from a connected sdf file
    http://localhost/mapserver2014//fusion/templates/mapguide/slate/index.html?ApplicationDefinition=Library%3a%2f%2fparcels.ApplicationDefinition
    &LAYERNAME=parcels
    &KEYNAME=PARCEL_LINK
    &KEY=PAR_1234
    &ISSTRING=0

  19. 22 Leonardo Parra
    June 10, 2014 at 3:42 am

    Great Blog, Gordon. Keep up the good work! Do you have anything about creating REST connections? I’ve already seen your videos from AU

  20. 23 Alejandro Vasquez
    May 3, 2015 at 4:34 am

    Gordon, Thanks for sharing this procedure. I would like to share my experience applying this code:

    1. The curly brakets in the initial function call are not closed in the original article,
    2. In the php code, when you copy and paste the code, the lines with double quotes must be reviewed and quotes has to be corrected. looks like wordpress uses openning and clossing quotes, all quotes must follow standard ascii format [ ” ” ] not [ “ ” ]
    var AJAXURL = “/mapguide/GETSELECTIONXML.php?MAPNAME=” + MAPNAME;
    3. taking care of these points and previous Gordon’s notes related to the location of files. It must run like a charm. I used OS Mapguide 2.6 on Apache and it works!.

    Gordon, a question for you: could you please, illustrate how to include a zoom factor in the code?

  21. May 16, 2015 at 1:02 am

    If you want to change the scale, you can add the following to the index.html (templates like Slate).

    script type=”text/javascript” src=”../../../layers/MapGuide/MapGuideViewerApi.js”></script

    Then you can use the Zoom to View:
    ZoomToView(centerX, centerY, scale, true);

    You will have to figure out the x and y (I would just get the current map center and set the scale):

    var theLon=iFrameMap.Fusion.getWidgetById('Map').oMapOL.getCenter().lat;
    var theLat=iFrameMap.Fusion.getWidgetById('Map').oMapOL.getCenter().lon;

  22. 25 Alejandro vasquez
    May 16, 2015 at 12:50 pm

    Gordon thxs for your Help. This is a great point of support for what I’m working on.

  23. 26 Josimar
    January 19, 2016 at 3:56 am

    Hi, I just starting working with AIMS 2014 and I’m exactly trying to get the “highlight objects in the map” feature working. I followed your example, and it’s working as expected. Now, I wanna do the same but with my own deployed map, which I uploaded through the Infrastructure Studio and created a Flexible Layout. The URL that I’m getting for my app is as follows:
    http://localhost/mapserver2014//fusion/templates/mapguide/slate/index.html?ApplicationDefinition=Library%3a%2f%2fskyMain%2fSKyCurrentMapLayout.ApplicationDefinition

    As you can see, I’m using the slate template too, but I don’t know how exactly I should complete the URL in order to get objects selected as in your example.

    Another question(and probably the most important for me) is: How do you know the exact ID’s of the objects? I can’t seem to find such ID’s anywhere.

    Note: The map that I’m using is using a dwg file as datasource, so, I’m kinda lost about identifying any proper ‘object Id’.

    Any comments that could guide me to find a solution would be really appreciated,
    Thanks in advance.

  24. January 19, 2016 at 1:46 pm

    You really have to know your data. If you have a layer that you want to search on, you can put the column you need and its value.

    So if you have a layer called “Roads” and it has a column called “ROAD_NAME” you can search for “Main St.” with the following URL:

    http://whateverserveryouhavenamedorinstalled/mapserver2014/fusion/templates/mapguide/slate/index.html?LAYERNAME=Roads&KEYNAME=ROAD_NAME&KEY=Main St.&ISSTRING=1

    So you have to know your data to get it to work or perhaps you have a “Parcel” layer with a column called “ROLLNUMBER” with a value of “12345” then you might have the following URL:

    http://someotherpowerfulserveryouinstalled/mapserver2014/fusion/templates/mapguide/slate/index.html?LAYERNAME=Parcel&KEYNAME=ROLLNUMBER&KEY12345&ISSTRING=0

  25. 28 Josimar
    January 21, 2016 at 1:51 am

    Thanks for the quick answer Gordon. I understand the logic of the search, the layer name, the property and its value in order to do the search, that’s no problem at all. My problem is that our map is created in Autodesk Autocad(2015) and, as you may know, the resulting file from there is a .dwg, which I upload afterwards to the AIMS as my data(source) through the Infrastructure Studio and the layers are generated automatically. When I edit any layer generated from the dwg into the Infrastructure Studio, the only properties(columns) shown are just default geometric ones, such as “handle”, “layerhandle”, “lineweight”, “linetypescale”, etc. The ‘handle’ property work as ‘ID’, but the problem is that I have no control on its value, seems to be automatically generated once the dwg file is uploaded into the Infrastructure Studio. In your case, your example is using .sdf files as data sources to get all the properties that you need, such as the “ID”.

    I know it seems that I’m going off topic but please understand that in order to get my own Map to do what you are explaining in this tutorial it’s completely necessary for me to understand how the data used to create the map is actually being uploaded.

    Could you give me a hint on what application/software/tool was used to create the example map?
    And if you have any idea about how to customize the object properties from the Autodesk Autocad and carry them when saved as .dwg file, it would be huge help.

    Thanks in advance, and sorry if my comments are unclear.

  26. January 21, 2016 at 2:18 pm

    Oh, if your source data does not have columns to search by then you can’t use this method.

    If you are using DWG, and you are using AutoCAD Map 3D (or Civil 3D) you can add Object Data as custom properties.
    Otherwise the dumb DWG is not capable of having custom properties.

    The example uses files such as SDF or SHP with are GIS files that have searchable columns such as Parcel_ID or Road_number.

    The data is everything. Smart data, smart GIS. The source data needs attribute data if you want to use the search.

  27. 30 Josimar
    February 2, 2016 at 3:14 am

    Thanks for answering, Gordon. As you explained, my mistake was that I tried to use a DWG file that was not carrying any “real” data that I could work with besides the default geometric info of the drawing. I switched to Autocad Map 3D, connected to an SQL database and created some template links so the objects actually get data that can be more useful. Your example works correctly, with my drawing too, but I’m facing another problem and I hope you can guide me a little bit on that; Here is the case:

    – My drawing was initially created in Autocad, which is just a raw DWG.
    – I open the drawing in Autocad Map 3D and I set additional attributes via template links to a data base.
    – In order to deploy it into Infrastructure Map Server, I had to export the drawing into an SDF which creates a feature class for each layer and it successfully carries the objects’ linked data.
    – The problem is that the generated map doesn’t keep the original drawing ‘shapes’, in other words, if my drawing was originally colored and some objects were using some specific geometry, they become a black and white Map with default geometry for each object, such as basic square, circle, triangle, etc.
    – If I only export the dwg without exporting into SDF, the drawing keeps all its characteristics, shapes, colors, etc, BUT it doesn’t carry the data from the template links.
    – I know that I can ‘retouch’ the layers in the Infrastructure studio and set some design for each layer, but this is like doing my drawing two times.

    Is there any way available in which I can export my DWG (with data from template links) into Infrastructure Map Server without losing its original attributes (colors, geometry shapes, data)?

    Thanks in advance, great blog, you are doing an excellent work here, cheers to you.

  28. 31 Tecatito
    June 22, 2016 at 5:02 am

    Hi Gordon, would this work with the Basic Layout(Ajax viewer)?

    Thanks.

  29. June 22, 2016 at 10:00 am

    The JavaScript part would not work as they have different apis.
    But with some tweaking it could work..

  30. 33 Tecatito
    June 22, 2016 at 10:18 am

    I tried with Fusion viewers(Aqua, Slate, etc) and it works perfectly. As you said, it didn’t work on Basic Layout when I tried following the same steps. By any chance, do you have any tutorial or guide on how to accomplish the same on Basic Layout?

    Thanks for your advises.

  31. 35 Tecatito
    June 22, 2016 at 10:31 am

    Thanks a lot for the quick response. I’m gonna give it a try. 🙂

  32. 36 Mark C
    July 27, 2016 at 5:24 pm

    Followed everything, but im getting an error. Invalid Characters. Ajax Callback

  33. 37 Mark C
    July 27, 2016 at 5:43 pm

    Any help will do. my code is like this var AJAXURL = “/MapGuide/fusion/widgets/Redline/GETSELECTIONXML.php?MAPNAME=” + MAPNAME;
    AJAXURL = AJAXURL + “&SESSION=” + SESSION;
    AJAXURL = AJAXURL + “&KEYNAME=EmployeeId”;
    AJAXURL = AJAXURL + “&LAYERNAME=Office Assignments”;
    AJAXURL = AJAXURL + “&KEY=2686”;
    AJAXURL = AJAXURL + “&ISSTRING=1”;

  34. July 27, 2016 at 7:34 pm

    Perhaps get rid of the spaces in the layer name called Office Assignments…maybe “OFFICE_ASSIGNMENTS”

  35. 39 Mark C
    July 27, 2016 at 7:48 pm

    Thanks Gordon for the quick response. I did this and still the same. Funny thing is, the xml result when doing this code and the xmlresult on the build-in fusion task query feature is the same. But this gets me an error of invalid characters.

  36. 40 Mark C
    July 27, 2016 at 7:58 pm

    I tried using the mapWidget.query(option), but searching with polygons or points always highlight 2 objects. If i use .filter =’featid=1844′ i get invalid character error again.. driving me nuts..

  37. July 27, 2016 at 9:49 pm

    Check your GETSELECTIONXML.php and make sure you do not have any weird ECHOs or Returns…

  38. 42 Armando Gaeta
    January 5, 2017 at 12:06 pm

    Hi, I’m trying your code for the StandardFusionViewer. The code is slightly different from the SlateTemplate, and in fact I’m not able to trigger the javascript function once the map is loaded because I’m not able to intercept WHEN the map is loaded. Have you experienced that? How can be solved this? Thanks! A.R. Gaeta

  39. February 13, 2017 at 2:15 pm

    The only part that is the same as the Fusion would be the PHP part.
    Check out how to get the onload event here.
    https://trac.osgeo.org/mapguide/wiki/CodeSamples/JavaScript/AJAXViewerEventHooking

  40. 44 Armando Gaeta
    February 13, 2017 at 3:30 pm

    Thanks a lot for your response. I’m gonna give it a try.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


Gordon Luckett

Arrow Geomatics Inc's Gordon Luckett

Contact

gordon dot luckett at arrowgeo dot com 1-519-837-9500 (Arrow Geomatics Inc.)

Checkout MapGuide Guy’s Youtube Channel

gordonluckett@twitter


%d bloggers like this: