[OpenLayers-Users] International date line and bounds [SEC=UNCLASSIFIED]

Piero Campa piero.campa at gmail.com
Thu Aug 5 12:38:45 EDT 2010


Of course: the code in the attachment.
Anyway, for more clearness:

°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
OpenLayers.Handler.myRegularPolygon = OpenLayers.Class.create();
OpenLayers.Handler.myRegularPolygon.prototype = OpenLayers.Class.inherit
(OpenLayers.Handler.RegularPolygon, {
	
	/**
	 * Constant: LIMIT
	 * Maximum Polygon width (default is 180° of longitude)
	 */
	LIMIT: 20037508.34,
	
	/**
	 * Constant: GLOBE_LON
	 * Longitude width of 'one globe' (360°)
	 */
	GLOBE_LON: 20037508.34*2,
	
	/**
	 * Property: lastX
	 * X-coordinate of the last mouse movement
	 */
	lastX: null,
	
	/**
	 * Property: IDL
	 * Boolean: mouse is beyond IDL.
	 */
	IDL: false,
	 
    /**
    * Method: downFeature
    * Start drawing a new feature
    *
    * Parameters:
    * evt - {Event} The drag start event
    */
	down: function(evt){
		var aoiLayer = // enter here the OpenLayers.Layer.Vector layer controlled
by the DrawFeature Control

		// Remove preceding boxes (max 1 polygon per layer, if you want to)
		if (aoiLayer.features.length > 0) {
			for (var i = 0; i < aoiLayer.features.length; i++) 
				aoiLayer.removeFeatures(aoiLayer.features[i]);
		}
		
		this.fixedRadius = !!(this.radius);
		var maploc = this.map.getLonLatFromPixel(evt.xy); // wrapped lonlat
		
		// Check if I'm on an inactive side-globe	
		var map_size = map_vac.getSize();
		var center = parseInt(map_size.w / 2, 10);
		var centerLonLat = this.map.getLonLatFromPixel(new
OpenLayers.Pixel(center,0));
		var centerPx = this.map.getPixelFromLonLat(new OpenLayers.LonLat(0,0)); 
			 
		if(evt.xy.x < map_size.w / 2 && maploc.lon > 0 && 
			(centerLonLat.lon < 0 || centerPx.x > evt.xy.x)) {				
				// I'm on left side-globe
				maploc.lon -= this.GLOBE_LON;
				this.IDL = true;
		} else if (evt.xy.x > map_size.w / 2 && maploc.lon < 0 && 
			(centerLonLat.lon > 0 || centerPx.x < evt.xy.x)) {
				// I'm on right side-globe
				maploc.lon += this.GLOBE_LON;
				this.IDL = true;
		}
		
		this.origin = new OpenLayers.Geometry.Point(maploc.lon, maploc.lat);
		
		// Store this.origin position (pixel) in the map, to handle IDL
		AOI.originPx = new OpenLayers.Pixel(evt.xy.x, evt.xy.y); // AOI.originPx
is a global variable
		
		// create the new polygon
		if (!this.fixedRadius || this.irregular) {
			// smallest radius should not be less one pixel in map units
			// VML doesn't behave well with smaller
			this.radius = this.map.getResolution();
		}
		if (this.persist) {
			this.clear();
		}
		this.feature = new OpenLayers.Feature.Vector();
		this.createGeometry();
		this.layer.addFeatures([this.feature], {
			silent: true
		});
		this.layer.drawFeature(this.feature, this.style);		
	},

	move: function(evt) {
        var maploc = this.map.getLonLatFromPixel(evt.xy);	
        var point = new OpenLayers.Geometry.Point(maploc.lon, maploc.lat);
			
		// Check if IDL has been crossed
		if (Math.abs(this.lastX - point.x) >= this.LIMIT && this.lastX != null) {
			this.IDL = (this.IDL == true) ? false : true; // Toggle
		}
		
		// IDL handler
		var sign;
		var diff = point.x - this.origin.x;		
		
		if (this.IDL) {
			// Continue drawing one-piece AOI 
			//point.x = this.lastX; // Cut at the IDL			
			(evt.xy.x > this.map.getSize().w / 2) ? (sign = 1) : (sign = -1);
			
			if (Math.abs(diff) < this.LIMIT)	 
				point.x = this.origin.x + this.LIMIT * sign;
			else
				point.x = point.x + this.GLOBE_LON * sign;			
		}
		else if (Math.abs(diff) >= this.LIMIT) {
				// The point is beyond the IDL (diff is low but origin and point are on
different globes)
				(evt.xy.x > AOI.originPx.x) ? (sign = 1) : (sign = -1);			
				point.x = this.origin.x + this.LIMIT * sign;	
		} else {			
			// Not IDL nor >180°: do nothing 
		}
		
		// Keep trace of the movement direction
		this.lastX = maploc.lon;
		
		// Continue with default OL instructions:
		if (this.irregular) {
			var ry = Math.sqrt(2) * Math.abs(point.y - this.origin.y) / 2;
			this.radius = Math.max(this.map.getResolution() / 2, ry);
		}
		else 
			if (this.fixedRadius) {
				this.origin = point;
			}
			else {
				this.calculateAngle(point, evt);
				this.radius = Math.max(this.map.getResolution() / 2,
point.distanceTo(this.origin));
			}
		this.modifyGeometry();
		if (this.irregular) {
			/* The new polygon is first calculated as it would be regular (origin in
the centre and
			 * same-length sides), then it is resized by x/y ratio and moved so that
the origin
			 * is again the first clicked point (handled by the 'down' method).
			 */
			var dx = point.x - this.origin.x;
			var dy = point.y - this.origin.y;
			var ratio;
			if (dy == 0) {
				ratio = dx / (this.radius * Math.sqrt(2));
			}
			else {
				ratio = dx / dy;
			}
			this.feature.geometry.resize(1, this.origin, ratio);
			this.feature.geometry.move(dx / 2, dy / 2);
		}
		this.layer.drawFeature(this.feature, this.style);
		
		// Keep trace of origin pixel to manage IDL in this.move() function
		this.originPixel = this.layer.getViewPortPxFromLonLat(this.origin);
    },


    /** @final @type String */
    CLASS_NAME: "OpenLayers.Handler.myRegularPolygon"
})
°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°

This way the name of the handler is myRegularPolygon.
I had to make use of external variables such as the OpenLayers.Layer.Vector
layer controlled by the DrawFeature control and a global variable in which
to store the pixel location of the origin of the polygon (I didn't
understand yet why I could not store it as a property of the class),
anyway... This has been tested with irregular rectangles.
Piero
-- 
View this message in context: http://osgeo-org.1803224.n2.nabble.com/International-date-line-and-bounds-tp2541265p5377316.html
Sent from the OpenLayers Users mailing list archive at Nabble.com.



More information about the Users mailing list