ThinkGeo.com    |     Documentation    |     Premium Support

Multipoint in the map

Hello


i would like to use a multipoint shape in edition mode (in the edit overlay) i have several questions :

- it is possible to move all the points at the same time, but this feature can be done by selecting another node which has exactly the same appearance than my actual points, is is possible to change the css of the point that enables me to move all the other points ?



- is it possible to delete a single point ?



- is it possible to create a point and add it to my multipoint



- apparently if i select a single point (in edit mode) of a multipoint and click on the map aside the point, the multipoint disappears, is it normal?





i dont know if it is possible but i would to do everything in javascript.

thanks for your help



Sorry for the delay in responding your post. We will give you the detailed answers to your questions tomorrow. Thank you.

 Sebastien,


 
The web Edition doesn’t support the drawing multipoint shape directly, but the workaround is using OpenLayers library.
 
1. The style of virtual points can be changed via virtualStyle of ModifyFeature that can be available from the code below:      
 
OnMapCreated = function(map) {
            var modifyFeature = map.getControlsByClass("OpenLayers.Control.ModifyFeature");
            if (modifyFeature[0] != undefined) {
                modifyFeature.virtualStyle.fillOpacity = 0.8;
                modifyFeature.virtualStyle.strokeOpacity = 0.3;
                  }
            }
 Please refer to dev.openlayers.org/releases/...rs-js.html for more properties of virtualStyle.
 
2. The logic about deleting a shape is defined in ModifyFeture, we can overwrite it to make sure it can apply to delete single point. The code is like below, also you can redefine it following your custom logic.
 
OnMapCreating = function(map) {
            OpenLayers.Control.ModifyFeature.prototype.handleKeypress = function(evt) {
                var code = evt.keyCode;
 
                // check for delete key
                if (this.feature &&
           OpenLayers.Util.indexOf(this.deleteCodes, code) != -1) {
                    var vertex = this.dragControl.feature;
                    if (vertex.geometry.CLASS_NAME == "OpenLayers.Geometry.Point") {
                        if (vertex &&
               !this.dragControl.handlers.drag.dragging) {
                            // remove the vertex
                            this.layer.removeFeatures([this.feature])
                            this.resetVertices();
                            this.setFeatureState();
                            this.onModification(this.feature);
                            this.layer.events.triggerEvent("featuremodified",
                                               { feature: this.feature });
                        }
                    }
                    else if (vertex &&
               OpenLayers.Util.indexOf(this.vertices, vertex) != -1 &&
               !this.dragControl.handlers.drag.dragging &&
               vertex.geometry.parent) {
                        // remove the vertex
                        vertex.geometry.parent.removeComponent(vertex.geometry);
                        this.layer.drawFeature(this.feature,
                                       this.selectControl.renderIntent);
                        this.resetVertices();
                        this.setFeatureState();
                        this.onModification(this.feature);
                        this.layer.events.triggerEvent("featuremodified",
                                               { feature: this.feature });
                    }
                }
            }
        }
 
3. All the features drawn are stored in the Vector Layer named “EditOvlay”, so we can modify the feature before submiting the feature to server. Here are the steps that we can do:
      a. Find the layer named “EditOverlay”:
            var map = Map1.GetOpenlayersMap();
            var editOverlay = map.getLayer("EditOverlay");
      b. Loop the features in editOverlay and check the class_name of each featue to make sure it is OpenLayers.Geometry.Point and
OpenLayers.Geometry.MultiPoint.
      c. Add the point drawn into MultiPoint.
 
   
Any questions please let us know.
 
Thanks,
Johnny 
 

 For the first point, i tried your code and it doesnt change what i want, maybe i didnt make myself clear enough. When you edit a feature you can drag all the feature using a point drawn at the center of the feature. The problem with a multipoint is that all the points of the multipoint have exactly the same look and feel as the point drawn to drag the feature when editing it. So it is quite disturbing for the end user.


 


I tried the second but it doesnt work. What i do, is insert a multipoint, edit it, then mouse hover a point click on delete button and nothing happen.


 


Thanks for your help


Sebastien



Hi, sebastien

Sorry for delay response. First off, I want to confirm with you about the requirements. You want to add a MultipointShape on map, and user could edit it or drag it, then user could delete it using the "Delete" key when hovering the point, also you need they have different styles between poinst.

In fact, they do have different styles between the center point of feature and the points of feature by default. But maybe you set the IsReshapable property of Map1.EditOverlay.EditSettings ture, so we will draw control points on the multi points of features using the default style in order to support delete it, so they have the same look. So please set it false and try it.

Also if you want to set the style of the center point in the MultipointShape manually, you could the style object of Map1.EditOverlay. If you want to set the style of points when you select the feature, please refer to the code in the attachment.


Another thing is that IsResizable will conflict with IsReshapable, so if you set IsResizable true and the IsReshapable won't work.


If you want to delete a point, you just need to set the IsReshapable property true and don't set  IsResizable ture.


Hope this could help you. Please refer to the sample in the attachment if you want to know more in deta


Thanks,


Khalil


 



1968-MapShapes.zip (2.87 KB)

for my styling problem, see the files enclosed in testTemp.zip the source code.


In thinkgeo_multipoints_style.zip you ll see what my problem is.


Basically i display a multipoint of three points, when i edit my shape (by clicking on the edit button) another point appears (the one i encircled in the step2.jpg). The style of this point is exactly the same as the other one. This causes the impression that this new point is part of my multipoints which is not. I would like to customize only this point so that the user will know that he can drag the multipoint (ideally i would like to have an image instead of this point).


 


This sample is basic, of course in the real world, my multipoint will be much more complex.


thanks for your help


sebastien


 


 



1986-TestTemp.zip (2.92 KB)
1987-thinkgeo_multipoints_style.zip (383 KB)

Hi,   Sebastien,


Yes, I know your problem. I have clarified the reason why it happens in the last reply post.

If user sets DrawMode as "Modify", all the EditSettings (IsDraggable, IsReshapable, IsResizable, IsRotatable ) are enabled. 


For example, if user displays a multipoint shape that consists of three points, and just call the method "Map1.SetDrawMode('Modify');", we will draw another three points using the same style (default style) on these three points; these points are called control points in order to support re-shape. 

Anyway, if you just want to customize only the center point; the attachment is the sample code for you. I have added some nessecery client-side method on your posted code of last reply. Also I have added some comments for you. Please replace the url of the image which is related to an external graphic that will be used for rendering point.  


Thanks,


Khalil



1991-MultiPoints.zip (3.93 KB)

it works very well thanks a lot. 
 Is it possible to display the point to move the multipoint as soon as we click on the edit button. For the moment we have to click on a node. 
  
 thanks for your help

Sebastien,


If you want to implement this functionality; you just need to trigger the click event automatically. 


Please refer to the code below:</p

function editme() {
    Map1.SetDrawMode('Modify');
    var modifyControl = Map1.GetMapParser().paintControls["Modify"];
    var layer = Map1.GetMapParser().editOverlay;
    //Get the MultipointShape feature
    var feature = layer.features[0];
    var selectControl = modifyControl.selectControl.clickFeature(feature);
}

Thanks,

Khalil



 perfect exactly what i want.


 


I tried the code Johnny gave me but it does not work. 


 I tried to integrate it in the enclosed file. When i click on the edit button, hover a node and then press delete key, the node does not disappear. do you have any idea?


 


thanks for your help



OnMapCreating = function(map) {
            OpenLayers.Control.ModifyFeature.prototype.handleKeypress = function(evt) {
                var code = evt.keyCode;
 
                // check for delete key
                if (this.feature &&
           OpenLayers.Util.indexOf(this.deleteCodes, code) != -1) {
                    var vertex = this.dragControl.feature;
                    if (vertex.geometry.CLASS_NAME == "OpenLayers.Geometry.Point") {
                        if (vertex &&
               !this.dragControl.handlers.drag.dragging) {
                            // remove the vertex
                            this.layer.removeFeatures([this.feature])
                            this.resetVertices();
                            this.setFeatureState();
                            this.onModification(this.feature);
                            this.layer.events.triggerEvent("featuremodified",
                                               { feature: this.feature });
                        }
                    }
                    else if (vertex &&
               OpenLayers.Util.indexOf(this.vertices, vertex) != -1 &&
               !this.dragControl.handlers.drag.dragging &&
               vertex.geometry.parent) {
                        // remove the vertex
                        vertex.geometry.parent.removeComponent(vertex.geometry);
                        this.layer.drawFeature(this.feature,
                                       this.selectControl.renderIntent);
                        this.resetVertices();
                        this.setFeatureState();
                        this.onModification(this.feature);
                        this.layer.events.triggerEvent("featuremodified",
                                               { feature: this.feature });
                    }
                }
            }
        }


1992-TestMultipoints2.zip (4.21 KB)

Sebastien,


I think there is no need to use the code Johnny has provided in the previous reply post now.  The codes I have provided for you that could implement your implements absolutely. I have integrated these codes into one page. Please check out the attachment. I have tested it using IE7, IE8 and Firefox 3.5 or later.


Thanks,


Khalil



1993-TestMultiPoints.zip (4 KB)

 


thanks a lot, last thing i try to do is to implement the point 3 of johnny answer.


when i draw a single point, i want to add it in my multipoint. so i triggered the clientDrawEnd and try to implement what johnny says, but how can i add the feature to my multipoint ? 


 


 


 


thanks for your help


Sebastien



        var clientDrawEnd = function(feature) {
            alert(feature);

            var modifyControl = Map1.GetMapParser().paintControls["Modify"];
            var layer = Map1.GetMapParser().editOverlay;
            for (var i in layer.features) {
                if (layer.features[i].geometry.CLASS_NAME == "OpenLayers.Geometry.MultiPoint") {
                    //how can i add feature (my point) into the multipoint
                } 
            }
        }


Hi, sebastien 
  
 I don’t know what clientDrawEnd function means. I think you could refer to the documentation of OpenLayers if you want to use client-side funtion. 
 Here is link for the API documentation OpenLayers. 
 dev.openlayers.org/docs/files/OpenLayers/Geometry/MultiPoint-js.html  
  
 Thanks, 
 Khalil

I used the following code to customize the look and feel of the point to move the editoverlay, is it possible to do the same with the rotate option : Map1.EditOverlay.EditSettings.IsRotatable = true; 


 


 




var OnMapCreating = function(map) {
            OpenLayers.Control.ModifyFeature.prototype.collectDragHandle = function() {
                var style_mark = OpenLayers.Util.extend({}, OpenLayers.Feature.Vector.style['default']);

                style_mark.graphicWidth = 24;
                style_mark.graphicHeight = 20;
                style_mark.graphicXOffset = -(style_mark.graphicWidth / 2);  // this is the default value
                style_mark.graphicYOffset = -style_mark.graphicHeight;
                //Here you specify the image what you want
                style_mark.externalGraphic = "../Resources/Images/markers/move.jpg";
                // Here is the tooltip, but graphicTitle only works in Firefox and Internet Explorer
                style_mark.graphicTitle = "Move here to move the whole shape";

                var geometry = this.feature.geometry;
                var center = geometry.getBounds().getCenterLonLat();
                var originGeometry = new OpenLayers.Geometry.Point(center.lon, center.lat);

                //Here you add the style you have defined before to the point feature.
                var origin = new OpenLayers.Feature.Vector(originGeometry, null, style_mark);
                originGeometry.move = function(x, y) {
                    OpenLayers.Geometry.Point.prototype.move.call(this, x, y);
                    geometry.move(x, y);
                };
                origin._sketch = true;
                this.dragHandle = origin;
                this.layer.addFeatures([this.dragHandle], { silent: true });
            }
        }


thanks for your help

Hi, sebastien


I think you need to override another method if you still want the rotate control point has another different style; it's the same with the drag control point. Please refer to the code below:



OpenLayers.Control.ModifyFeature.prototype.collectRadiusHandle = function() {
    var geometry = this.feature.geometry;
    var bounds = geometry.getBounds();
    var center = bounds.getCenterLonLat();
    var originGeometry = new OpenLayers.Geometry.Point(center.lon, center.lat);
    var radiusGeometry = new OpenLayers.Geometry.Point(bounds.right, bounds.bottom);

    var style_mark = OpenLayers.Util.extend({}, OpenLayers.Feature.Vector.style['default']);

    style_mark.graphicWidth = 24;
    style_mark.graphicHeight = 20;
    style_mark.graphicXOffset = -(style_mark.graphicWidth / 2);  // this is the default value
    style_mark.graphicYOffset = -style_mark.graphicHeight;
    //Here you specify the image what you want
    style_mark.externalGraphic = "../../theme/default/samplepic/circle.png";
    // Here is the tooltip, but graphicTitle only works in Firefox and Internet Explorer
    style_mark.graphicTitle = "this is the rotate control point";

    //Here you add the style you have defined before to the point feature.
    var radius = new OpenLayers.Feature.Vector(radiusGeometry, null, style_mark);
    var resize = (this.mode & OpenLayers.Control.ModifyFeature.RESIZE);
    var reshape = (this.mode & OpenLayers.Control.ModifyFeature.RESHAPE);
    var rotate = (this.mode & OpenLayers.Control.ModifyFeature.ROTATE);

    radiusGeometry.move = function(x, y) {
        OpenLayers.Geometry.Point.prototype.move.call(this, x, y);
        var dx1 = this.x - originGeometry.x;
        var dy1 = this.y - originGeometry.y;
        var dx0 = dx1 - x;
        var dy0 = dy1 - y;
        if (rotate) {
            var a0 = Math.atan2(dy0, dx0);
            var a1 = Math.atan2(dy1, dx1);
            var angle = a1 - a0;
            angle *= 180 / Math.PI;
            geometry.rotate(angle, originGeometry);
        }
        if (resize) {
            var scale, ratio;
            // 'resize' together with 'reshape' implies that the aspect 
            // ratio of the geometry will not be preserved whilst resizing 
            if (reshape) {
                scale = dy1 / dy0;
                ratio = (dx1 / dx0) / scale;
            } else {
                var l0 = Math.sqrt((dx0 * dx0) + (dy0 * dy0));
                var l1 = Math.sqrt((dx1 * dx1) + (dy1 * dy1));
                scale = l1 / l0;
            }
            geometry.resize(scale, originGeometry, ratio);
        }
    };
    radius._sketch = true;
    this.radiusHandle = radius;
    this.layer.addFeatures([this.radiusHandle], { silent: true });
}

Thanks,


Khalil



Hello


i tried to put the gis module in a user control but it says that Map1 is undefined whereas without the usercontrol my code worked very well.


thanks for your help



2039-multipoint.zip (5.62 KB)

Hi, sebastien



If you want to dump the ThinkGeo map control into a Web User Control; I think you need to use the ClientID instead of ID.

For example, if I have a "mainControl" designated on my base aspx page, and then I place a user control into it "usercontrol1" which has a text box named "txtFirstName", here's what happens: ID="mainContol_usercontrol1_txtFirstName" . It's the same with your sample, the id of map control is 'moduleCarto_Map1'.

So you should replace Map1 with <%=Map1.ClientID %>. Please refer to the code below:


 var OnMapCreated = function(map) {
        Map1 = <%=Map1.ClientID %>;
if (Map1.GetMapParser() != null && Map1.GetMapParser().paintControls != null) {
~~~~~~~~~~~~~~
}
 }


Thanks,

Khalil



Hello


I have a problem and i dont know how to solve it:


I enclosed the sourcecode in testMultipoint.zip and the different step that points out the bug. 


Basically i created a multipoint on serverside then edit the multipoint then when i click elsewhere the multipoint disappear.


 


do you have any idea of what is going on?


thanks for your help.


 



2054-testMultipoint.zip (5.39 KB)
2051-step_1.zip (467 KB)
2052-step_2.zip (373 KB)

Hi, sebastien



Please don't place the OnMapCreated callback function after the html form closing tag just before that; and then you could get the result what you want. If you want to know it in detail please refer to the attachment.



Thanks,

Khalil



2056-TestMultiPointsV2.zip (5.44 KB)

 hello


your code does not work, in the enclosed file there is no onMapCreated event and the problem still occurs, I put the gis map in a usercontrol.


to reproduce the problem:


- click on "createMultiPoints" button


- click on "editmode" button


- click on a node to edit it, then click beside and the multipoint disappear


 


I test map app on firefox 3.5 (dont know if it is related)


thanks for your help.


 



2065-TestMultipointv3.zip (6.16 KB)