ThinkGeo.com    |     Documentation    |     Premium Support

Showing tooltip for line, point feature shape file on client side

Hi



I am working with shape files which draws line and point layer on Virutal Earth. Currently we have 22 such shape files. Some shape files are very small in size while their dbf files are big in size.  The largest dbf of one shape file is 60 mb in size.



At page load, 22 layers are drawn out of shape file on top of VE.



How do I display Tooltip from shape file column on client side when user hover any of point or line layer on the map.



Find attached image for all layers view to get idea about how big shape(s) files are.



Thanks

Hiren



921-alllayers1.png (92 KB)

Hiren,



Let’s say you have understood how it works in our earlier post which is posted at gis.thinkgeo.com/Support/Dis...fault.aspx by the time 05/26/2009.



The only difference is buffer the click point to make it to a MultiPolygonShape in the callback, then use QueryTools to get the features which are intersected with the MultiPolygonShape. The first item of its return collection is what you need. The rest things are getting the information you need and transferring back to client like the old way. Here is the main code.stateLayer.QueryTools.GetFeaturesIntersecting(circle, ReturningColumnsType.AllColumns);


Any questions please let me know.



Thanks,

Howard.

 



Hi Howard,



Thanks for quick response.

I used your sample code from previous post and made some changes to incorporate my shape files with VE.



I tried to create MultiPolygonShape using buffer method of latlong (in RaiseCallbackEvent)  and then passing MultiPolygonShape to Lyr_Access_Point.QueryTools.GetFeaturesIntersecting(……)  method.



I am not getting any features count through QueryTools.



I think I did not understand how to get buffer when user mouse hover it on point or line feature on map.



I have attached code and screenshot of page for your reference. 



Attached page shows code for point type, how to I achieve same with line type feature. In short I need tool tip for all layers (point and line) 



Thanks

Hiren

 



922-ShowToolTip.zip (177 KB)

Hiren,



I see; the problem is the Buffer distance is too small to intersect with the click shape. And that method has a potential problem which is when you zoom in several times, the buffer shape will be bigger and bigger which means your result is less and less accuracy.



Now I have a better solution for you which is to get a specific are in any zoom level. Please see the code and commends below.
// get the click position.
PointShape clickWorldPosition = e.Position;

// convert to screen point.
ScreenPointF clickScreenPoint = Map1.ToScreenCoordinate(clickWorldPosition);

// 5 is the radius to buffer the click point.
ScreenPointF clickNextScreenPoint = new ScreenPointF(clickScreenPoint.X + 5, clickScreenPoint.Y);

// calculate the distance is world coordinate of the radius.
double worldDistance = ExtentHelper.GetWorldDistanceBetweenTwoScreenPoints(Map1.CurrentExtent, clickScreenPoint, clickNextScreenPoint, (float)Map1.WidthInPixels, (float)Map1.HeightInPixels, GeographyUnit.DecimalDegree, DistanceUnit.Meter);

// calculate the buffer which you need.
MultipolygonShape clickArea = clickWorldPosition.Buffer(worldDistance, GeographyUnit.DecimalDegree, DistanceUnit.Meter);

 “ClickArea” should be the shape which to query the intersected shapes.



If you have any questions please let me know.



Thanks,

Howard











Howard,


 


Thanks for reply.


I checked the code, it works fine on Map1_Click(..) event. I got features count for selected point on a map.


 


But I need it to display as ToolTip on mouse hover on any feature layer using client side. I don’t want to display toop tip on map click.


 


Below is code that works on map click event.


//===========================================


            // get the click position.


            PointShape clickWorldPosition = e.Position;


 


            // convert to screen point.


            ScreenPointF clickScreenPoint = Map1.ToScreenCoordinate(clickWorldPosition);


 


            // 5 is the radius to buffer the click point.


            ScreenPointF clickNextScreenPoint = new ScreenPointF(clickScreenPoint.X + 5, clickScreenPoint.Y);


 


            // calculate the distance is world coordinate of the radius.


            double worldDistance = ExtentHelper.GetWorldDistanceBetweenTwoScreenPoints(Map1.CurrentExtent, clickScreenPoint, clickNextScreenPoint, (float)Map1.WidthInPixels, (float)Map1.HeightInPixels, GeographyUnit.Meter, DistanceUnit.Meter);


 


            // calculate the buffer which you need.


            MultipolygonShape clickArea = clickWorldPosition.Buffer(worldDistance, GeographyUnit.Meter, DistanceUnit.Meter);


 


            ShapeFileFeatureLayer Lyr_Access_Point = (ShapeFileFeatureLayer)((LayerOverlay)Map1.CustomOverlays[0]).Layers["Lyr_Access_Point"];


            Lyr_Access_Point.Open();


            Collection<Feature> features = Lyr_Access_Point.QueryTools.GetFeaturesIntersecting(clickArea, ReturningColumnsType.AllColumns);


 


            if (features.Count > 0)


            {


                callbackResult = features[0].ColumnValues["Type_Name"];


            }


  


//===============


I tried following code to show tooltip on clinet side into RaiseCallbackEvent(string eventArgument), but got error. 


I converted eventArgument to PointShape.. that did not worked… I got error at following line


 


double worldDistance = ExtentHelper.GetWorldDistanceBetweenTwoScreenPoints(Map1.CurrentExtent, clickScreenPoint, clickNextScreenPoint, (float)Map1.WidthInPixels, (float)Map1.HeightInPixels, GeographyUnit.Meter, DistanceUnit.Meter);


 


Error:


     Map1.WidthInPixels & Map1.HeightInPixels value only available after postback.


 



Here is code..



        public void RaiseCallbackEvent(string eventArgument)


        {  


            string[] lonlatStrings = eventArgument.Split(',');


            // get the click position.


            PointShape clickWorldPosition = new PointShape(double.Parse(lonlatStrings[0]), double.Parse(lonlatStrings[1]));


            // convert to screen point.


            ScreenPointF clickScreenPoint = Map1.ToScreenCoordinate(clickWorldPosition);


            // 5 is the radius to buffer the click point.


            ScreenPointF clickNextScreenPoint = new ScreenPointF(clickScreenPoint.X + 5, clickScreenPoint.Y);


            // calculate the distance is world coordinate of the radius.


            double worldDistance = ExtentHelper.GetWorldDistanceBetweenTwoScreenPoints(Map1.CurrentExtent, clickScreenPoint, clickNextScreenPoint, (float)Map1.WidthInPixels, (float)Map1.HeightInPixels, GeographyUnit.Meter, DistanceUnit.Meter);


 


            // calculate the buffer which you need.


            MultipolygonShape clickArea = clickWorldPosition.Buffer(worldDistance, GeographyUnit.Meter, DistanceUnit.Meter);


 


            ShapeFileFeatureLayer Lyr_Access_Point = (ShapeFileFeatureLayer)((LayerOverlay)Map1.CustomOverlays[0]).Layers["Lyr_Access_Point"];


            Lyr_Access_Point.Open();


            Collection<Feature> features = Lyr_Access_Point.QueryTools.GetFeaturesIntersecting(clickArea, ReturningColumnsType.AllColumns);


 


            if (features.Count > 0)


            {


                callbackResult = features[0].ColumnValues["Type_Name"];


            }


            }                      


 


Thanks


Hiren




Hiren, 
  
 If you set map’s width and height to 100%, we cannot get the actual width and height of map on the server side in the first life circle. So the only way to get it is doing a post back and we synchronize these properties for you. But you use these properties in the page load so that this exception throws. 
  
 The only way to get the width and height is use JavaScript to pass the actual width and height of map div back to server by callback parameters. Just like the point I passed back. 
  
 Hope it make sense; any questions please let me know. 
  
 Thanks, 
 Howard






<object
classid="clsid:38481807-CA0E-42D2-BF39-B33AF135CC4D" id=ieooui>

st1\:*{behavior:url(#ieooui) }




Hi Howard,


 


Tool tip showing on client side works absolutely fine out of shape file. What I have done so far is, I created separate prototype for different functionality to test web control with my client requirement.


 


Today I started to integrate each of these prototypes into final page one by one.


 


While integrating Tooltip code into main page I got following  page error, it didn’t even load page.


 


The Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>). 


 


Note: My main page has <st1:city w:st="on"><st1:place w:st="on">AJAX</st1:place></st1:city> toolkit tab control.


 


Inside Java script, function beginToolTipsRequest has <%=…….%> code.


 


Below is java script funciton


 


        var beginToolTipsRequest = function() {


            var lonlat = this.map.getLonLatFromViewPortPx(this.xy);


            var args = lonlat.lon + ',' + lonlat.lat + ',' + vScale; 


            var context = $get('divTooltips');


            //alert(vScale);


            <%=ClientScript.GetCallbackEventReference(Page, "args", "showToolTips", "context") %>


        };


 


Is there any simple replacement for this line? Before adding tool tip code, main page works fine.


 


I have also attached code for your reference.


 


Thanks


Hiren




961-Main.zip (17.3 KB)
963-Main_Before_TT_Code.GIF (65.5 KB)

Hi Hiren,



As far as I know, there are three simple ways to register this script; please try the following tips. 

1, I think you already know how it works currently.<%=ClientScript.GetCallbackEventReference(Page, "args", "showToolTips", "context") %>


2,use ClientScript to generate the script on the server side.string callbackString = ClientScript.GetCallbackEventReference(this, "args", "showToolTips", "context");
string script = "var beginToolTipsRequest = function(){//..."
    + callbackString
    + "}";
ClientScript.RegisterClientScriptBlock(GetType(), "BeginCallback", "var beginToolTipsRequest = function(...", true);



3, use callback script directly on the client side.var beginToolTipsRequest = function() {
    var lonlat = this.map.getLonLatFromViewPortPx(this.xy);
    var args = lonlat.lon + ',' + lonlat.lat + ',' + vScale; 
    var context = $get('divTooltips');
    WebForm_DoCallback('__Page',args,showToolTips,context,null,false);
};



Hope it helps; any questions please let me know.



Thanks,

Howard

 











Howard,


 


I tried option 2nd and 3rd.


with 3 rd option I got following error: 


 


Error:'_theFormPostData' is undefined


 


Attached is modified Java Script.


 


Using 2nd option, creating script on server side I got same above error.


I created script to register on server in page load event.


 


            if (!Page.IsPostBack)


            {


                string callbackString = ClientScript.GetCallbackEventReference(this, "args", "showToolTips", "context");


                string script = "var beginToolTipsRequest = function() { var lonlat = this.map.getLonLatFromViewPortPx(this.xy); var args = lonlat.lon + ',' + lonlat.lat + ',' + vScale; var context = $get('divTooltips');"


                    + callbackString


                    + "}";


                ClientScript.RegisterClientScriptBlock(GetType(), "BeginCallback", script, true)


             };


 


Thanks


Hiren


 


 




967-JS_code.txt (4.1 KB)

Hiren, 



Could you tell me what's the version of Web Edition are you using? If you are using the version which is released after 3.1.16, please commend out the following JavaScript in your attached file.
var postData = decodeURIComponent(__theFormPostData);
var startData = postData.substr(0, postData.indexOf('&'));
var endData = postData.substr(postData.indexOf('&'), postData.length - postData.indexOf('&'));
__theFormPostData = startData + ',' + map.getScale().toString() + endData;



Any questions please let me know.



Thanks,

Howard











Howard,


 


I’m using web edition 3.0.0.0 ver.


 


Thanks


Hiren




Hiren, 



Sorry for I didn't say the version clearly. 3.0.0.0 is Assembly version which is not what I needed. Please check the file version for me. Or the following code helps you find what the version you are using.
string version = Map.Version;


Hope it helps.



Thanks,

Howard



Howard,


It shows "MapSuiteCore:3.1.16;WebEdition:3.1.16" 


Hiren



Hiren, 
  
 Could upgrade the web edition to the latest version which you can download in our web site. Or provide me a quick project which I can use for debugging? 
  
 Also, paste the callstack of the JavaScript exception if possible. 
  
 Thanks, 
 Howard









Howard,


 


Please find attached tooltip solution.


Kindly include WebEdition & MapSuiteCore reference to solution.


In this solution, as per your suggestion


 


1. I’m trying to create & register java script on server side.


 


2. Also I tried to use following on client side.


 



var beginToolTipsRequest = function() {
    var lonlat = this.map.getLonLatFromViewPortPx(this.xy);
    var args = lonlat.lon + ',' + lonlat.lat + ',' + vScale; 
    var context = $get('divTooltips');
    WebForm_DoCallback('__Page',args,showToolTips,context,null,false);

};

 


None of above worked. It did not even fired ‘RaiseCallbackEvent’ event


 


Thanks


Hiren




977-ToolTip1.zip (9.56 KB)

Hiren,



I don't have the data in your code, but when I replaced into our own data, it works fine. The callback is raised correctly. I recommend upgrading your current version to the latest one. You have missed our two public release; in another word, you missed many fixed bugs.



Here is a screenshot of your sample project which runs to the break point I set in the callback.





If you have any questions please let me know.



Thanks,

Howard











Howard,


 


I’m scared to upgrade new version as I have alpha release next week.


I am not sure but upgrade to new version may stop working with functionality/module or may require code change. If that is case, can I download old version again?


 


Thanks


Hiren












Howard,


 


I don’t mind to send you data file, but its 10 MB size after zipping it.


Do you have any specific upload space or email id where I can send this file?


 


Thanks


Hiren




Hiren, 
  
 I think there is not the big of the deal to upgrade to our latest version. You can do it safely follow this steps. 
  
 1. Backup the old DLL you are reference currently. It’s under “[Installed Folder]\ThinkGeo\Map Suite Web Evaluation Edition 3.0\Developer Reference” 
 2. Download our latest DLL package and replace the old one. 
 3. Copy the files in system32 folder to “C:\WINDOWS\system32”. 
 4. Rebuild your solution. 
 5. Clear the IE cache and your server cache if it’s on. 
 6. Delete the JavaScript I mentioned above which is used for fixing a bug in 3.1.16. 
 7. Run your application. 
  
 It won’t take much time on configuration and testing. 
  
 If it won’t work please let me know. 
  
 Thanks, 
 Howard









Howard,


 


Thanks for quick response.


I will try with new version. Let you know if there is any issue.


 


Hiren