Formats now support reprojection using internalProjection and
externalProjection properties. These allow for the reprojection of data -- OpenLayers users with SphericalMercator get this built in for EPSG:900913, and other users can use the external proj4js library available from MapBuilder SVN to add support for any number of projections. This means that featres can be, for example, transformed from a KML doc in 4326 to Spherical Mercator before being added to a layer, making using SphericalMercator slightly more enticing. r=elemoine (Closes #1039) git-svn-id: http://svn.openlayers.org/trunk/openlayers@5516 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
@@ -55,6 +55,32 @@
|
|||||||
<script src="../lib/OpenLayers.js"></script>
|
<script src="../lib/OpenLayers.js"></script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
var map, vectors, formats;
|
var map, vectors, formats;
|
||||||
|
function updateFormats() {
|
||||||
|
var in_options = {
|
||||||
|
'internalProjection': map.baseLayer.projection,
|
||||||
|
'externalProjection': new OpenLayers.Projection(OpenLayers.Util.getElement("inproj").value)
|
||||||
|
}
|
||||||
|
var out_options = {
|
||||||
|
'internalProjection': map.baseLayer.projection,
|
||||||
|
'externalProjection': new OpenLayers.Projection(OpenLayers.Util.getElement("outproj").value)
|
||||||
|
}
|
||||||
|
formats = {
|
||||||
|
'in': {
|
||||||
|
wkt: new OpenLayers.Format.WKT(in_options),
|
||||||
|
geojson: new OpenLayers.Format.GeoJSON(in_options),
|
||||||
|
georss: new OpenLayers.Format.GeoRSS(in_options),
|
||||||
|
gml: new OpenLayers.Format.GML(in_options),
|
||||||
|
kml: new OpenLayers.Format.KML(in_options)
|
||||||
|
},
|
||||||
|
'out': {
|
||||||
|
wkt: new OpenLayers.Format.WKT(out_options),
|
||||||
|
geojson: new OpenLayers.Format.GeoJSON(out_options),
|
||||||
|
georss: new OpenLayers.Format.GeoRSS(out_options),
|
||||||
|
gml: new OpenLayers.Format.GML(out_options),
|
||||||
|
kml: new OpenLayers.Format.KML(out_options)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
function init(){
|
function init(){
|
||||||
map = new OpenLayers.Map('map');
|
map = new OpenLayers.Map('map');
|
||||||
var wms = new OpenLayers.Layer.WMS( "OpenLayers WMS",
|
var wms = new OpenLayers.Layer.WMS( "OpenLayers WMS",
|
||||||
@@ -74,13 +100,7 @@
|
|||||||
map.addControl(select);
|
map.addControl(select);
|
||||||
select.activate();
|
select.activate();
|
||||||
|
|
||||||
formats = {
|
updateFormats();
|
||||||
wkt: new OpenLayers.Format.WKT(),
|
|
||||||
geojson: new OpenLayers.Format.GeoJSON(),
|
|
||||||
georss: new OpenLayers.Format.GeoRSS(),
|
|
||||||
gml: new OpenLayers.Format.GML(),
|
|
||||||
kml: new OpenLayers.Format.KML()
|
|
||||||
};
|
|
||||||
|
|
||||||
map.setCenter(new OpenLayers.LonLat(0, 0), 1);
|
map.setCenter(new OpenLayers.LonLat(0, 0), 1);
|
||||||
}
|
}
|
||||||
@@ -89,7 +109,7 @@
|
|||||||
var type = document.getElementById("formatType").value;
|
var type = document.getElementById("formatType").value;
|
||||||
// second argument for pretty printing (geojson only)
|
// second argument for pretty printing (geojson only)
|
||||||
var pretty = document.getElementById("prettyPrint").checked;
|
var pretty = document.getElementById("prettyPrint").checked;
|
||||||
var str = formats[type].write(feature, pretty);
|
var str = formats['out'][type].write(feature, pretty);
|
||||||
// not a good idea in general, just for this demo
|
// not a good idea in general, just for this demo
|
||||||
str = str.replace(/,/g, ', ');
|
str = str.replace(/,/g, ', ');
|
||||||
document.getElementById('output').value = str;
|
document.getElementById('output').value = str;
|
||||||
@@ -98,7 +118,7 @@
|
|||||||
function deserialize() {
|
function deserialize() {
|
||||||
var element = document.getElementById('text');
|
var element = document.getElementById('text');
|
||||||
var type = document.getElementById("formatType").value;
|
var type = document.getElementById("formatType").value;
|
||||||
var features = formats[type].read(element.value);
|
var features = formats['in'][type].read(element.value);
|
||||||
var bounds;
|
var bounds;
|
||||||
if(features) {
|
if(features) {
|
||||||
if(features.constructor != Array) {
|
if(features.constructor != Array) {
|
||||||
@@ -164,6 +184,15 @@
|
|||||||
<input id="prettyPrint" type="checkbox"
|
<input id="prettyPrint" type="checkbox"
|
||||||
name="prettyPrint" value="1" />
|
name="prettyPrint" value="1" />
|
||||||
<br />
|
<br />
|
||||||
|
Input Projection: <select id="inproj" onchange='updateFormats()'>
|
||||||
|
<option value="EPSG:4326" selected="selected">EPSG:4326</option>
|
||||||
|
<option value="EPSG:900913">Spherical Mercator</option>
|
||||||
|
</select> <br />
|
||||||
|
Output Projection: <select id="outproj" onchange='updateFormats()'>
|
||||||
|
<option value="EPSG:4326" selected="selected">EPSG:4326</option>
|
||||||
|
<option value="EPSG:900913">Spherical Mercator</option>
|
||||||
|
</select>
|
||||||
|
<br />
|
||||||
<textarea id="text">paste text here...</textarea>
|
<textarea id="text">paste text here...</textarea>
|
||||||
<br />
|
<br />
|
||||||
<input type="button" value="add feature" onclick="deserialize();" />
|
<input type="button" value="add feature" onclick="deserialize();" />
|
||||||
|
|||||||
@@ -11,6 +11,34 @@
|
|||||||
*/
|
*/
|
||||||
OpenLayers.Format = OpenLayers.Class({
|
OpenLayers.Format = OpenLayers.Class({
|
||||||
|
|
||||||
|
/**
|
||||||
|
* APIProperty: externalProjection
|
||||||
|
* {<OpenLayers.Projection>} When passed a externalProjection and
|
||||||
|
* internalProjection, the format will reproject the geometries it
|
||||||
|
* reads or writes. The externalProjection is the projection used by
|
||||||
|
* the content which is passed into read or which comes out of write.
|
||||||
|
* In order to reproject, a projection transformation function for the
|
||||||
|
* specified projections must be available. This support may be
|
||||||
|
* provided via proj4js or via a custom transformation function. See
|
||||||
|
* {<OpenLayers.Projection.addTransform>} for more information on
|
||||||
|
* custom transformations.
|
||||||
|
*/
|
||||||
|
externalProjection: null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* APIProperty: internalProjection
|
||||||
|
* {<OpenLayers.Projection>} When passed a externalProjection and
|
||||||
|
* internalProjection, the format will reproject the geometries it
|
||||||
|
* reads or writes. The internalProjection is the projection used by
|
||||||
|
* the geometries which are returned by read or which are passed into
|
||||||
|
* write. In order to reproject, a projection transformation function
|
||||||
|
* for the specified projections must be available. This support may be
|
||||||
|
* provided via proj4js or via a custom transformation function. See
|
||||||
|
* {<OpenLayers.Projection.addTransform>} for more information on
|
||||||
|
* custom transformations.
|
||||||
|
*/
|
||||||
|
internalProjection: null,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor: OpenLayers.Format
|
* Constructor: OpenLayers.Format
|
||||||
* Instances of this class are not useful. See one of the subclasses.
|
* Instances of this class are not useful. See one of the subclasses.
|
||||||
|
|||||||
@@ -147,6 +147,10 @@ OpenLayers.Format.GML = OpenLayers.Class(OpenLayers.Format.XML, {
|
|||||||
var parser = this.parseGeometry[type.toLowerCase()];
|
var parser = this.parseGeometry[type.toLowerCase()];
|
||||||
if(parser) {
|
if(parser) {
|
||||||
geometry = parser.apply(this, [nodeList[0]]);
|
geometry = parser.apply(this, [nodeList[0]]);
|
||||||
|
if (this.internalProjection && this.externalProjection) {
|
||||||
|
geometry.transform(this.externalProjection,
|
||||||
|
this.internalProjection);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
OpenLayers.Console.error("Unsupported geometry type: " +
|
OpenLayers.Console.error("Unsupported geometry type: " +
|
||||||
type);
|
type);
|
||||||
@@ -619,6 +623,11 @@ OpenLayers.Format.GML = OpenLayers.Class(OpenLayers.Format.XML, {
|
|||||||
* APIMethod: buildGeometryNode
|
* APIMethod: buildGeometryNode
|
||||||
*/
|
*/
|
||||||
buildGeometryNode: function(geometry) {
|
buildGeometryNode: function(geometry) {
|
||||||
|
if (this.externalProjection && this.internalProjection) {
|
||||||
|
geometry = geometry.clone();
|
||||||
|
geometry.transform(this.internalProjection,
|
||||||
|
this.externalProjection);
|
||||||
|
}
|
||||||
var className = geometry.CLASS_NAME;
|
var className = geometry.CLASS_NAME;
|
||||||
var type = className.substring(className.lastIndexOf(".") + 1);
|
var type = className.substring(className.lastIndexOf(".") + 1);
|
||||||
var builder = this.buildGeometry[type.toLowerCase()];
|
var builder = this.buildGeometry[type.toLowerCase()];
|
||||||
|
|||||||
@@ -231,6 +231,10 @@ OpenLayers.Format.GeoJSON = OpenLayers.Class(OpenLayers.Format.JSON, {
|
|||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (this.internalProjection && this.externalProjection) {
|
||||||
|
geometry.transform(this.externalProjection,
|
||||||
|
this.internalProjection);
|
||||||
|
}
|
||||||
return geometry;
|
return geometry;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -526,6 +530,11 @@ OpenLayers.Format.GeoJSON = OpenLayers.Class(OpenLayers.Format.JSON, {
|
|||||||
* {Object} An object representing the geometry.
|
* {Object} An object representing the geometry.
|
||||||
*/
|
*/
|
||||||
'geometry': function(geometry) {
|
'geometry': function(geometry) {
|
||||||
|
if (this.internalProjection && this.externalProjection) {
|
||||||
|
geometry = geometry.clone();
|
||||||
|
geometry.transform(this.internalProjection,
|
||||||
|
this.externalProjection);
|
||||||
|
}
|
||||||
var geometryType = geometry.CLASS_NAME.split('.')[2];
|
var geometryType = geometry.CLASS_NAME.split('.')[2];
|
||||||
var data = this.extract[geometryType.toLowerCase()].apply(this, [geometry]);
|
var data = this.extract[geometryType.toLowerCase()].apply(this, [geometry]);
|
||||||
var json;
|
var json;
|
||||||
|
|||||||
@@ -152,6 +152,12 @@ OpenLayers.Format.GeoRSS = OpenLayers.Class(OpenLayers.Format.XML, {
|
|||||||
var feature = this.gmlParser.parseFeature(where[0]);
|
var feature = this.gmlParser.parseFeature(where[0]);
|
||||||
geometry = feature.geometry;
|
geometry = feature.geometry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.internalProjection && this.externalProjection) {
|
||||||
|
geometry.transform(this.externalProjection,
|
||||||
|
this.internalProjection);
|
||||||
|
}
|
||||||
|
|
||||||
return geometry;
|
return geometry;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -324,6 +330,11 @@ OpenLayers.Format.GeoRSS = OpenLayers.Class(OpenLayers.Format.XML, {
|
|||||||
* {DOMElement} A gml node.
|
* {DOMElement} A gml node.
|
||||||
*/
|
*/
|
||||||
buildGeometryNode: function(geometry) {
|
buildGeometryNode: function(geometry) {
|
||||||
|
if (this.internalProjection && this.externalProjection) {
|
||||||
|
geometry = geometry.clone();
|
||||||
|
geometry.transform(this.internalProjection,
|
||||||
|
this.externalProjection);
|
||||||
|
}
|
||||||
var node;
|
var node;
|
||||||
// match Polygon
|
// match Polygon
|
||||||
if (geometry.CLASS_NAME == "OpenLayers.Geometry.Polygon") {
|
if (geometry.CLASS_NAME == "OpenLayers.Geometry.Polygon") {
|
||||||
|
|||||||
@@ -132,6 +132,10 @@ OpenLayers.Format.KML = OpenLayers.Class(OpenLayers.Format.XML, {
|
|||||||
var parser = this.parseGeometry[type.toLowerCase()];
|
var parser = this.parseGeometry[type.toLowerCase()];
|
||||||
if(parser) {
|
if(parser) {
|
||||||
geometry = parser.apply(this, [nodeList[0]]);
|
geometry = parser.apply(this, [nodeList[0]]);
|
||||||
|
if (this.internalProjection && this.externalProjection) {
|
||||||
|
geometry.transform(this.externalProjection,
|
||||||
|
this.internalProjection);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
OpenLayers.Console.error("Unsupported geometry type: " +
|
OpenLayers.Console.error("Unsupported geometry type: " +
|
||||||
type);
|
type);
|
||||||
@@ -450,6 +454,11 @@ OpenLayers.Format.KML = OpenLayers.Class(OpenLayers.Format.XML, {
|
|||||||
* {DOMElement}
|
* {DOMElement}
|
||||||
*/
|
*/
|
||||||
buildGeometryNode: function(geometry) {
|
buildGeometryNode: function(geometry) {
|
||||||
|
if (this.internalProjection && this.externalProjection) {
|
||||||
|
geometry = geometry.clone();
|
||||||
|
geometry.transform(this.internalProjection,
|
||||||
|
this.externalProjection);
|
||||||
|
}
|
||||||
var className = geometry.CLASS_NAME;
|
var className = geometry.CLASS_NAME;
|
||||||
var type = className.substring(className.lastIndexOf(".") + 1);
|
var type = className.substring(className.lastIndexOf(".") + 1);
|
||||||
var builder = this.buildGeometry[type.toLowerCase()];
|
var builder = this.buildGeometry[type.toLowerCase()];
|
||||||
|
|||||||
@@ -94,6 +94,10 @@ OpenLayers.Format.Text = OpenLayers.Class(OpenLayers.Format, {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (set) {
|
if (set) {
|
||||||
|
if (this.internalProjection && this.externalProjection) {
|
||||||
|
geometry.transform(this.externalProjection,
|
||||||
|
this.internalProjection);
|
||||||
|
}
|
||||||
var feature = new OpenLayers.Feature.Vector(geometry, attributes, style);
|
var feature = new OpenLayers.Feature.Vector(geometry, attributes, style);
|
||||||
features.push(feature);
|
features.push(feature);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,6 +60,19 @@ OpenLayers.Format.WKT = OpenLayers.Class(OpenLayers.Format, {
|
|||||||
if(this.parse[type]) {
|
if(this.parse[type]) {
|
||||||
features = this.parse[type].apply(this, [str]);
|
features = this.parse[type].apply(this, [str]);
|
||||||
}
|
}
|
||||||
|
if (this.internalProjection && this.externalProjection) {
|
||||||
|
if (features &&
|
||||||
|
features.CLASS_NAME == "OpenLayers.Feature.Vector") {
|
||||||
|
features.geometry.transform(this.externalProjection,
|
||||||
|
this.internalProjection);
|
||||||
|
} else if (features && typeof features == "object") {
|
||||||
|
for (var i = 0; i < features.length; i++) {
|
||||||
|
var component = features[i];
|
||||||
|
component.geometry.transform(this.externalProjection,
|
||||||
|
this.internalProjection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return features;
|
return features;
|
||||||
},
|
},
|
||||||
@@ -97,6 +110,11 @@ OpenLayers.Format.WKT = OpenLayers.Class(OpenLayers.Format, {
|
|||||||
if(!this.extract[type]) {
|
if(!this.extract[type]) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
if (this.internalProjection && this.externalProjection) {
|
||||||
|
geometry = geometry.clone();
|
||||||
|
geometry.transform(this.internalProjection,
|
||||||
|
this.externalProjection);
|
||||||
|
}
|
||||||
data = this.extract[type].apply(this, [geometry]);
|
data = this.extract[type].apply(this, [geometry]);
|
||||||
pieces.push(type.toUpperCase() + '(' + data + ')');
|
pieces.push(type.toUpperCase() + '(' + data + ')');
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user