Add support for reprojection of vector formats when loading data. This allows

for the definition of a 'projection' option on a layer. IF this projection 
object exists, it will be used to create the format's internal/external 
projection options, making it such that any data loaded will be reprojected 
to the map's projection automatically. r=pagameba (Closes #1273, #1225, #1269) 


git-svn-id: http://svn.openlayers.org/trunk/openlayers@5828 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
crschmidt
2008-01-20 20:33:54 +00:00
parent 7a19fd6a95
commit f28a1c314a
7 changed files with 159 additions and 21 deletions
+17 -2
View File
@@ -28,6 +28,13 @@ OpenLayers.Layer.GML = OpenLayers.Class(OpenLayers.Layer.Vector, {
* {<OpenLayers.Format>} The format you want the data to be parsed with. * {<OpenLayers.Format>} The format you want the data to be parsed with.
*/ */
format: null, format: null,
/**
* APIProperty: formatOptions
* {Object} Hash of options which should be passed to the format when it is
* created. Must be passed in the constructor.
*/
formatOptions: null,
/** /**
* Constructor: OpenLayers.Layer.GML * Constructor: OpenLayers.Layer.GML
@@ -127,8 +134,16 @@ OpenLayers.Layer.GML = OpenLayers.Class(OpenLayers.Layer.Vector, {
if (!doc || request.fileType!="XML") { if (!doc || request.fileType!="XML") {
doc = request.responseText; doc = request.responseText;
} }
var gml = this.format ? new this.format() : new OpenLayers.Format.GML(); var options = {};
OpenLayers.Util.extend(options, this.formatOptions);
if (this.map && !this.projection.equals(this.map.getProjectionObject())) {
options.externalProjection = this.projection;
options.internalProjection = this.map.getProjectionObject();
}
var gml = this.format ? new this.format(options) : new OpenLayers.Format.GML(options);
this.addFeatures(gml.read(doc)); this.addFeatures(gml.read(doc));
this.events.triggerEvent("loadend"); this.events.triggerEvent("loadend");
}, },
+47 -3
View File
@@ -29,6 +29,13 @@ OpenLayers.Layer.GeoRSS = OpenLayers.Class(OpenLayers.Layer.Markers, {
* Array({<OpenLayers.Feature>}) * Array({<OpenLayers.Feature>})
*/ */
features: null, features: null,
/**
* APIProperty: formatOptions
* {Object} Hash of options which should be passed to the format when it is
* created. Must be passed in the constructor.
*/
formatOptions: null,
/** /**
* Property: selectedFeature * Property: selectedFeature
@@ -69,8 +76,6 @@ OpenLayers.Layer.GeoRSS = OpenLayers.Class(OpenLayers.Layer.Markers, {
OpenLayers.Layer.Markers.prototype.initialize.apply(this, [name, options]); OpenLayers.Layer.Markers.prototype.initialize.apply(this, [name, options]);
this.location = location; this.location = location;
this.features = []; this.features = [];
this.events.triggerEvent("loadstart");
OpenLayers.loadURL(location, null, this, this.parseData);
}, },
/** /**
@@ -86,6 +91,36 @@ OpenLayers.Layer.GeoRSS = OpenLayers.Class(OpenLayers.Layer.Markers, {
this.clearFeatures(); this.clearFeatures();
this.features = null; this.features = null;
}, },
/**
* Method: loadRSS
* Start the load of the RSS data. Don't do this when we first add the layer,
* since we may not be visible at any point, and it would therefore be a waste.
*/
loadRSS: function() {
if (!this.loaded) {
this.events.triggerEvent("loadstart");
OpenLayers.loadURL(this.location, null, this, this.parseData);
this.loaded = true;
}
},
/**
* Method: moveTo
* If layer is visible and RSS has not been loaded, load RSS.
*
* Parameters:
* bounds - {Object}
* zoomChanged - {Object}
* minor - {Object}
*/
moveTo:function(bounds, zoomChanged, minor) {
OpenLayers.Layer.Markers.prototype.moveTo.apply(this, arguments);
if(this.visibility && !this.loaded){
this.events.triggerEvent("loadstart");
this.loadRSS();
}
},
/** /**
* Method: parseData * Method: parseData
@@ -113,7 +148,16 @@ OpenLayers.Layer.GeoRSS = OpenLayers.Class(OpenLayers.Layer.Markers, {
} }
} }
var format = new OpenLayers.Format.GeoRSS(); var options = {};
OpenLayers.Util.extend(options, this.formatOptions);
if (this.map && !this.projection.equals(this.map.getProjectionObject())) {
options.externalProjection = this.projection;
options.internalProjection = this.map.getProjectionObject();
}
var format = new OpenLayers.Format.GeoRSS(options);
var features = format.read(doc); var features = format.read(doc);
for (var i = 0; i < features.length; i++) { for (var i = 0; i < features.length; i++) {
+55 -11
View File
@@ -53,6 +53,13 @@ OpenLayers.Layer.Text = OpenLayers.Class(OpenLayers.Layer.Markers, {
* Array({<OpenLayers.Feature>}) * Array({<OpenLayers.Feature>})
*/ */
features: null, features: null,
/**
* APIProperty: formatOptions
* {Object} Hash of options which should be passed to the format when it is
* created. Must be passed in the constructor.
*/
formatOptions: null,
/** /**
* Property: selectedFeature * Property: selectedFeature
@@ -72,16 +79,6 @@ OpenLayers.Layer.Text = OpenLayers.Class(OpenLayers.Layer.Markers, {
initialize: function(name, options) { initialize: function(name, options) {
OpenLayers.Layer.Markers.prototype.initialize.apply(this, arguments); OpenLayers.Layer.Markers.prototype.initialize.apply(this, arguments);
this.features = new Array(); this.features = new Array();
if (this.location != null) {
var onFail = function(e) {
this.events.triggerEvent("loadend");
};
this.events.triggerEvent("loadstart");
OpenLayers.loadURL(this.location, null,
this, this.parseData, onFail);
}
}, },
/** /**
@@ -98,6 +95,43 @@ OpenLayers.Layer.Text = OpenLayers.Class(OpenLayers.Layer.Markers, {
this.features = null; this.features = null;
}, },
/**
* Method: loadText
* Start the load of the Text data. Don't do this when we first add the layer,
* since we may not be visible at any point, and it would therefore be a waste.
*/
loadText: function() {
if (!this.loaded) {
if (this.location != null) {
var onFail = function(e) {
this.events.triggerEvent("loadend");
};
this.events.triggerEvent("loadstart");
OpenLayers.loadURL(this.location, null,
this, this.parseData, onFail);
this.loaded = true;
}
}
},
/**
* Method: moveTo
* If layer is visible and Text has not been loaded, load Text.
*
* Parameters:
* bounds - {Object}
* zoomChanged - {Object}
* minor - {Object}
*/
moveTo:function(bounds, zoomChanged, minor) {
OpenLayers.Layer.Markers.prototype.moveTo.apply(this, arguments);
if(this.visibility && !this.loaded){
this.events.triggerEvent("loadstart");
this.loadText();
}
},
/** /**
* Method: parseData * Method: parseData
@@ -107,7 +141,17 @@ OpenLayers.Layer.Text = OpenLayers.Class(OpenLayers.Layer.Markers, {
*/ */
parseData: function(ajaxRequest) { parseData: function(ajaxRequest) {
var text = ajaxRequest.responseText; var text = ajaxRequest.responseText;
var parser = new OpenLayers.Format.Text();
var options = {};
OpenLayers.Util.extend(options, this.formatOptions);
if (this.map && !this.projection.equals(this.map.getProjectionObject())) {
options.externalProjection = this.projection;
options.internalProjection = this.map.getProjectionObject();
}
var parser = new OpenLayers.Format.Text(options);
features = parser.read(text); features = parser.read(text);
for (var i = 0; i < features.length; i++) { for (var i = 0; i < features.length; i++) {
var data = {}; var data = {};
+33
View File
@@ -53,6 +53,27 @@ OpenLayers.Layer.WFS = OpenLayers.Class(
* sent, this should be a subclass of OpenLayers.Feature * sent, this should be a subclass of OpenLayers.Feature
*/ */
featureClass: null, featureClass: null,
/**
* APIProperty: format
* {<OpenLayers.Format>} The format you want the data to be parsed with.
* Must be passed in the constructor. Should be a class, not an instance.
*/
format: null,
/**
* Property: formatObject
* {<OpenLayers.Format>} Internally created/managed format object, used by
* the Tile to parse data.
*/
formatObject: null,
/**
* APIProperty: formatOptions
* {Object} Hash of options which should be passed to the format when it is
* created. Must be passed in the constructor.
*/
formatOptions: null,
/** /**
* Property: vectorMode * Property: vectorMode
@@ -146,6 +167,18 @@ OpenLayers.Layer.WFS = OpenLayers.Class(
setMap: function(map) { setMap: function(map) {
if (this.vectorMode) { if (this.vectorMode) {
OpenLayers.Layer.Vector.prototype.setMap.apply(this, arguments); OpenLayers.Layer.Vector.prototype.setMap.apply(this, arguments);
var options = {
'extractAttributes': this.extractAttributes
};
OpenLayers.Util.extend(options, this.formatOptions);
if (this.map && !this.projection.equals(this.map.getProjectionObject())) {
options.externalProjection = this.projection;
options.internalProjection = this.map.getProjectionObject();
}
this.formatObject = this.format ? new this.format(options) : new OpenLayers.Format.GML(options);
} else { } else {
OpenLayers.Layer.Markers.prototype.setMap.apply(this, arguments); OpenLayers.Layer.Markers.prototype.setMap.apply(this, arguments);
} }
+1 -4
View File
@@ -133,10 +133,7 @@ OpenLayers.Tile.WFS = OpenLayers.Class(OpenLayers.Tile, {
doc = OpenLayers.parseXMLString(request.responseText); doc = OpenLayers.parseXMLString(request.responseText);
} }
if (this.layer.vectorMode) { if (this.layer.vectorMode) {
var gml = new OpenLayers.Format.GML({ this.layer.addFeatures(this.formatObject.read(doc));
'extractAttributes': this.layer.options.extractAttributes
});
this.layer.addFeatures(gml.read(doc));
} else { } else {
var resultFeatures = OpenLayers.Ajax.getElementsByTagNameNS( var resultFeatures = OpenLayers.Ajax.getElementsByTagNameNS(
doc, "http://www.opengis.net/gml", "gml", "featureMember" doc, "http://www.opengis.net/gml", "gml", "featureMember"
+5 -1
View File
@@ -21,6 +21,7 @@
t.ok( layer instanceof OpenLayers.Layer.GeoRSS, "new OpenLayers.Layer.GeoRSS returns object" ); t.ok( layer instanceof OpenLayers.Layer.GeoRSS, "new OpenLayers.Layer.GeoRSS returns object" );
t.eq( layer.location, georss_txt, "layer.location is correct" ); t.eq( layer.location, georss_txt, "layer.location is correct" );
var markers; var markers;
layer.loadRSS();
t.delay_call( 1, function() { t.delay_call( 1, function() {
t.eq( layer.markers.length, 40, "marker length is correct" ); t.eq( layer.markers.length, 40, "marker length is correct" );
var ll = new OpenLayers.LonLat(-71.142197, 42.405696); var ll = new OpenLayers.LonLat(-71.142197, 42.405696);
@@ -43,6 +44,7 @@
t.ok( layer instanceof OpenLayers.Layer.GeoRSS, "new OpenLayers.Layer.GeoRSS returns object" ); t.ok( layer instanceof OpenLayers.Layer.GeoRSS, "new OpenLayers.Layer.GeoRSS returns object" );
t.eq( layer.location, atom_xml, "layer.location is correct" ); t.eq( layer.location, atom_xml, "layer.location is correct" );
var markers; var markers;
layer.loadRSS();
t.delay_call( 1, function() { t.delay_call( 1, function() {
t.eq( layer.markers.length, 2, "marker length is correct" ); t.eq( layer.markers.length, 2, "marker length is correct" );
var ll = new OpenLayers.LonLat(29.9805, 36.7702); var ll = new OpenLayers.LonLat(29.9805, 36.7702);
@@ -153,7 +155,9 @@
map.addLayers([layer,otherLayer]); map.addLayers([layer,otherLayer]);
map.setCenter(new OpenLayers.LonLat(0,0),0); map.setCenter(new OpenLayers.LonLat(0,0),0);
var defaultIcon = OpenLayers.Marker.defaultIcon(); var defaultIcon = OpenLayers.Marker.defaultIcon();
t.delay_call( 1, function() { layer.loadRSS();
otherLayer.loadRSS();
t.delay_call( 2, function() {
t.ok(layer.markers[0].icon, "The layer has a icon"); t.ok(layer.markers[0].icon, "The layer has a icon");
t.eq(layer.markers[0].icon.url, defaultIcon.url, "The layer without icon has the default icon."); t.eq(layer.markers[0].icon.url, defaultIcon.url, "The layer without icon has the default icon.");
t.eq(otherLayer.markers[0].icon.url, the_icon.url,"The layer with an icon has that icon."); t.eq(otherLayer.markers[0].icon.url, the_icon.url,"The layer with an icon has that icon.");
+1
View File
@@ -21,6 +21,7 @@
t.plan( 5 ); t.plan( 5 );
layer = new OpenLayers.Layer.Text('Test Layer', { location: datafile }); layer = new OpenLayers.Layer.Text('Test Layer', { location: datafile });
layer.loadText();
t.ok( layer instanceof OpenLayers.Layer.Text, "new OpenLayers.Layer.Text returns object" ); t.ok( layer instanceof OpenLayers.Layer.Text, "new OpenLayers.Layer.Text returns object" );
t.eq( layer.location, datafile, "layer.location is correct" ); t.eq( layer.location, datafile, "layer.location is correct" );
var markers; var markers;