ThinkGeo.com    |     Documentation    |     Premium Support

Client Side Click Event

Hi,


I am wanting to execute some custom javascript on the client side when the user clicks the map.  How can I implement with this Map Suite?    Do you have any examples of this?


Thanks




Clint



Clint, 
  
 In the latest version (3.1.0, released early today), we have OnClientClick property to register click event at client side, here is the code: 
  
 
      Map1.OnClientClick = “function(map){alert(‘Client Click.’);}”;
 
   
 Any queries just let me know. 
  
 Ben

How would I get the coordinates of where the user clicked from OnClientClick? I would like to feed them into a spatial query via a WebMethod.

Rob, 



Here is the codes how to do it. 




// Here is the code for server. 
Map1.OnClientClick = "MapClientClick"; 




// Here is the code for client. 
var MapClientClick = function(e) { 
var lonlat = Map1.GetOpenLayersMap().getLonLatFromPixel(new OpenLayers.Pixel(e.clientX, e.clientY)); 
// lonlat is the mouse coordinate. 




Thanks, 



Ben 

 



Thanks Ben. That did the trick. 



But... 

I noticed that when I click the map, the latlong that the server returns from a full postback is different than the latlon that the client gets. This causes problems when clicking close to the border of a feature. Server grabs the correct feature, but the client grabs the adjacent one. Any ideas? Proj4 issue? OpenLayers issue? 


EDIT: Here is a sample point:

Server reports X: -13134470.761898108, Y: 3985999.9319463731

Client reports lon=-13134413.434126902, lat=3985918.7176038306

Thats 57 meters off on the X, and 81 meters off on the Y, which is enough to cause problems in smaller geographies.




-Rob



Rob, 
  
 It’s a breaking change between OpenLayers 2.6 and 2.7, the code should be like this: 
  
 var MapClientClick = function(e) {  
         var lonlat = Map1.GetOpenLayersMap().getLonLatFromPixel(e.xy); 
 } 
  
 “e.xy” means offset x and y of the view port.  
  
 Thanks, 
  
 Ben 


Great, works like a charm now!

Rob, 
  
   Glad it’s working now.  We don’t plan on any breaking changes anytime soon, or ever if possible.  Thanks for reporting this one, I am sure others will find it usefull. 
  
 David

Where can I see the javascipt API? I can use CloudPopup to display the coordinate in the Longitue, Latitude (meters), Decimal Degree and MGRS format and the distance measurement using server side. But there is performance issue. Is it possible to use javascript to implement them? 
  
 Thanks, 
  
 Wilson Jiang

 


Hi Wilson,
The client JavaScript API can be found at gis.thinkgeo.com/Support/Dis...fault.aspx . but it’s unable to show the popup with projected coordinates with JavaScript, because we need to do the projection on server side. Maybe you can try AJAX or ICallback. Please refer to the installation sample  “NewFeatures/MeasureMapTool.aspx” for how to do the distance measurement on client side.
 
Thanks,
 
Johnny

Is it possible to filter the features in ShapeFileFeatureLayer based on the values of an attribute (such as ID) using javascript? If so please give a sample code. Thanks, Wilson

Wilson,


I attached the sample code, let me know if you have questions.


Thanks


James



003_002_001_DisplayASimpleMap.zip (1.89 KB)

Hi James, 
  
 Thank you for providing the ICallBack sample. But I’ve already got the Ids to be filtered using PageMethod. Now I need only display the features with those Ids on the screen instead of all features from shape file. I can do that using server side. But don’t how to display features with those Ids without postbacking to server.

Wilson,


I have updated my sample, please look at it, hope it can give your some idea.


Thanks,


James



004_003_002_001_DisplayASimpleMap.zip (1.12 KB)

Hi James, 
  
 Thank you for the example. I almost got it working. But there is an issue to sync with server. Do you know how to remove the features in a layer using javascript. This layer is InMemoryFeatureLayer in server side. If I remove the layer from the map, I’ll lose the visibility. Thanks again, Wilson

Hi Wilson, 
  
 The InMemoryFeatureLayer created on the server side display as tile images on the client, hence we are unable to get the feature inside a InMemoryfeatureLayer on the client. I think you can use ICallback via JavaScript and remove the feature on server side.  
  
 Thanks, 
 Johnny

The sample works fine at the client side. But I have problem to retrieve them at the server side. Do I suppose to get those features using MapSAM.EditOverlay? Probably I did not set the feature attributes (fid, fieldvalues) correctly. I can not find those attributes in the API document. Please point it out. Thanks, Wilson 
  
 var featureWkt = sdzWktResult.SDZWkts.split(",WKT"); 
         var selectedSDZArr = sdzWktResult.selecedSDZs.split(","); 
  
         var vetorLayer = new OpenLayers.Layer.Vector(‘SDZ’); 
         vetorLayer.id = ‘SDZClient’; 
         //vetorLayer.displayInLayerSwitcher = false; 
         map.addLayer(vetorLayer);              
         var featureArray = new Array(); 
         for (var i = 0; i < featureWkt.length; i++) { 
            if (featureWkt != ‘’) { 
               var feature = new OpenLayers.Format.WKT().read(featureWkt); 
               // you can set more info if you need 
               feature.fid = selectedSDZArr
               feature.fieldvalues = featureWkt
               featureArray.push(feature); 
            } 
         } 
         vetorLayer.addFeatures(featureArray); 
         vetorLayer.redraw();

Wilson,


  You are misunderstanding the feature attributes, and I changed some of your codes, please see below:


var featureWkt = sdzWktResult.SDZWkts.split(",WKT");
var selectedSDZArr = sdzWktResult.selecedSDZs.split(",");
//you must use EditOverlay, sorry you can't change it
var vetorLayer = new OpenLayers.Layer.Vector('EditOverlay');
//you can set vetorlayer id, but it's useless, you won't use it
vetorLayer.id = 'SDZClient';
//you need get map first
var map = Map1.GetOpenLayersMap();
map.addLayer(vetorLayer);

var featureArray = new Array();
for (var i = 0; i < featureWkt.length; i++) {
    if (featureWkt != '') {
        var feature = new OpenLayers.Format.WKT().read(featureWkt[i]);
        // you can set more info if you need 
        // feature attributes is not necessary, you can set anything in anyname.
        // for example, if you use feature.fid, you can retrieve them at the server side use keyword 'fid' 
        // or you can use feature.blablabla, retrieve them at the server side use keyword 'blablabla'
        // you can set nothing if you didn't need to read information form a feature
        feature.fid = selectedSDZArr;
        feature.fieldvalues = featureWkt;
        featureArray.push(feature);
    }
}
vetorLayer.addFeatures(featureArray);
vetorLayer.redraw();

Any more questions please feel free to let me know.


Thanks,


James



Hi James, 
  
 I changed the name to ‘EditOverlay’. But I still can not get any features in server side when I postback the page. Anything wrong in my code: 
  
 Thanks,  
  
 Wilson 
  
          EditFeatureOverlay editOverlay = ( EditFeatureOverlay )MapSAM.EditOverlay; 
          logger.Debug( “editOverlay id:” + editOverlay.Id ); 
          logger.Debug( " edit overlay visible:" + editOverlay.IsVisible.ToString() ); 
          InMemoryFeatureSource fs = (InMemoryFeatureSource) editOverlay.FeatureSource; 
          fs.Open(); 
          Collection<Feature> allFeatures = fs.InternalFeatures; 
          logger.Debug( “No. of Features:” + allFeatures.Count); 
          foreach ( Feature f in allFeatures ) 
          { 
             string wkt = f.GetShape().GetWellKnownText(); 
             logger.Debug( “wkt:” + wkt ); 
             string id = f.Id; 
             logger.Debug( “id:” + id ); 
          } 
          fs.Close();

Wilson,


  I want to apologize first, I made a mistake about the EditOverlay, It is a keyword of MapCore, and the EditOverlay didn’t using like this way.


So I changed the code below:


var featureWkt = sdzWktResult.SDZWkts.split(",WKT");
var selectedSDZArr = sdzWktResult.selecedSDZs.split(",");
//please don’t use EditOverlay
var vetorLayer = new OpenLayers.Layer.Vector('CustomOverlay');
//you can set vetorlayer id, but it's useless, you won't use it
vetorLayer.id = 'SDZClient';
//you need get map first
var map = Map1.GetOpenLayersMap();
map.addLayer(vetorLayer);

var featureArray = new Array();
for (var i = 0; i < featureWkt.length; i++) {
    if (featureWkt != '') {
        var feature = new OpenLayers.Format.WKT().read(featureWkt[i]);
        // you can set more info if you need 
        // feature attributes is not necessary, you can set anything in anyname. 
        // But you still need a id.
        // for example, you can use feature.blablabla, retrieve them at the client
        // side use keyword 'blablabla' 
        // you can set nothing if you didn't need to read information form a feature
        feature.id = selectedSDZArr;
        feature.blablabla = featureWkt;
        featureArray.push(feature);
    }
}
vetorLayer.addFeatures(featureArray);
vetorLayer.redraw();

And you need to post the arguments to server when you need them: 
var callBackWithArguments = function () {
            var map = Map1.GetOpenLayersMap();
            var editLayer = map.getLayersByName('CustomOverlay')[0];
          // this is your callback method, you post a blablabla to server
            filtercall(editLayer.getFeatureById('recivedId').blablabla);
        }


Because every time when you changed something, you need to Synchronize with server, if you didn’t use MapCore to finish it, you will have a lot of work to do, so we are really not recommend you to display overlay by yourself.


And if you still want to display like this way, there is one more big problem, if the WKT is very long or Features are too many, browser will give you a warning about the javascript affect the performance.


Any more questions please feel free to let me know.


Thanks,


James