Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

In our app, we allow users to create features on maps. The boundaries of these features will later be converted into real-life latitude/longitude coordinates, but does not make sense if features are created outside the actual boundaries of the map.

In the above screenshot, I'd like to prevent the blue feature from being drawn so that its upper edge stays inside the actual map.

How could I do that? I couldn't find any reference to this in OpenLayers examples or documentation.

(Currently on 2.12-rc1)

share|improve this question
add comment

3 Answers

You could use an intersect check as Aragon specifies, combined with your own polygon handler, i've modified a polygon handler that won't let the user finish drawinf if the polygon is self-intersecting:

var myhandler = OpenLayers.Class(OpenLayers.Handler.Polygon, {

    addPoint: function(pixel) {
        var intersect = checkIntersect(this.polygon.geometry);
        if(intersect && this.polygon.geometry.components.length ==1){       
            //do nothing
        }
        else {
            OpenLayers.Handler.Polygon.prototype.addPoint.apply(this, arguments);
            if(intersect){
                this.undo();
            }
        }

    },
});

where the checkIntersect function checks self intersection

if you replace the checkIntersect with a function that checks for intersection with your area bounds, this should work.

use a normal DrawFeatureControl, but with your "myhandler" handler instead of a OpenLayers.Handler.Polygon

EDIT: edited with better implementation

For lines, you could try and subclass the Path handler in a similar way

share|improve this answer
    
Oh, that looks interesting. So this.undo(); will undo the last step in the polygon that would have been outside the boundaries? I have drawFeature enabled for rectangles and lines as well — is there a way to use this custom handler for all of these types without having to copy/paste it? –  slhck May 30 '12 at 11:00
    
what this handler does is override the finishGeometry function of the Polygon handler. If the geometry that is drawn is intersecting, it undoes the last point added to the geometry. One major drawback is that this will only trigger on the last point added, and thus only undo this.. So, actually a bad solution. Let me try to rewrite it... –  atlefren May 30 '12 at 11:06
    
Feel free to replace the answer's content rather than "appending" the right one. I'll try and see if I get this working. –  slhck May 30 '12 at 11:45
add comment

You can set an extent for your map object in openlayers, so user won't be able to browse and draw feature outside the extent.

restrictedExtent will limit user to these extents, take a look at the sample

var bounds = new OpenLayers.Bounds
(
    2819215.11322, 4234728.55108, 5081316.11322, 5269161.55108
);

var options = 
{
    maxExtent: bounds,
    numZoomLevels: 10,
    restrictedExtent: bounds,
    projection: "EPSG:3857",
    controls: [
        new OpenLayers.Control.Navigation(
        {dragPanOptions: {enableKinetic: true}}
    ),
        new OpenLayers.Control.ArgParser(),
        new OpenLayers.Control.Attribution()
    ]

};
map = new OpenLayers.Map('map_div',options);
share|improve this answer
    
This works, but only if the map is zoomed in close enough. Once I zoom out, I can still draw outside – what gives? How could I stop people from zooming out too much? –  slhck May 30 '12 at 10:24
    
you can use maxResolution and numZoomLevels options to prevent user zooming out too much take a look at dev.openlayers.org/docs/files/OpenLayers/Map-js.html mess around with maxResolution value and you will find a optimum number or use 'auto' –  bahadir May 30 '12 at 11:04
    
Hm, this seems to be more complicated since my map is a Zoomify tileset. I have to set maxResolution: Math.pow(2, this.baseLayer.numberOfTiers-1) and numZoomLevels: this.baseLayer.numberOfTiers+1 – everything else results in a wrong display. –  slhck May 30 '12 at 11:44
add comment

I think the best thing to do is that using openlayers intersection method to check if feature intersect with your map extent feature...

you can check out example here...

I will add a small example here if I can find time to write the code.

i hope it helps you...

share|improve this answer
    
But even then, what if the feature does intersect? It'd be annoying for the user to get an error message, having to draw the feature again. –  slhck May 30 '12 at 10:28
    
@atlefren has said what i meant. –  Aragon May 30 '12 at 11:24
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.