11
11
/**
12
12
* PHP Geometry/KML encoder/decoder
13
13
*
14
- * Mainly inspired/adapted from OpenLayers( http://www.openlayers.org )
14
+ * Mainly inspired/adapted from OpenLayers( http://www.openlayers.org )
15
15
* Openlayers/format/WKT.js
16
16
*
17
17
* @package sfMapFishPlugin
@@ -33,7 +33,7 @@ class KML extends GeoAdapter
33
33
public function read ($ kml ) {
34
34
return $ this ->geomFromText ($ kml );
35
35
}
36
-
36
+
37
37
/**
38
38
* Serialize geometries into a KML string.
39
39
*
@@ -44,24 +44,24 @@ public function read($kml) {
44
44
public function write (Geometry $ geometry , $ namespace = FALSE ) {
45
45
if ($ namespace ) {
46
46
$ this ->namespace = $ namespace ;
47
- $ this ->nss = $ namespace .': ' ;
47
+ $ this ->nss = $ namespace .': ' ;
48
48
}
49
49
return $ this ->geometryToKML ($ geometry );
50
50
}
51
-
51
+
52
52
public function geomFromText ($ text ) {
53
-
53
+
54
54
// Change to lower-case and strip all CDATA
55
55
$ text = mb_strtolower ($ text , mb_detect_encoding ($ text ));
56
56
$ text = preg_replace ('/<!\[cdata\[(.*?)\]\]>/s ' ,'' ,$ text );
57
-
57
+
58
58
// Load into DOMDOcument
59
59
$ xmlobj = new DOMDocument ();
60
60
@$ xmlobj ->loadXML ($ text );
61
61
if ($ xmlobj === false ) {
62
62
throw new Exception ("Invalid KML: " . $ text );
63
63
}
64
-
64
+
65
65
$ this ->xmlobj = $ xmlobj ;
66
66
try {
67
67
$ geom = $ this ->geomFromXML ();
@@ -73,7 +73,7 @@ public function geomFromText($text) {
73
73
74
74
return $ geom ;
75
75
}
76
-
76
+
77
77
protected function geomFromXML () {
78
78
$ geometries = array ();
79
79
$ geom_types = geoPHP::geometryList ();
@@ -98,24 +98,26 @@ protected function geomFromXML() {
98
98
$ geometries [] = $ this ->$ function ($ this ->xmlobj ->documentElement );
99
99
}
100
100
}
101
- return geoPHP::geometryReduce ($ geometries );
101
+ return geoPHP::geometryReduce ($ geometries );
102
102
}
103
-
103
+
104
104
protected function childElements ($ xml , $ nodename = '' ) {
105
105
$ children = array ();
106
- foreach ($ xml ->childNodes as $ child ) {
107
- if ($ child ->nodeName == $ nodename ) {
108
- $ children [] = $ child ;
106
+ if ($ xml ->childNodes ) {
107
+ foreach ($ xml ->childNodes as $ child ) {
108
+ if ($ child ->nodeName == $ nodename ) {
109
+ $ children [] = $ child ;
110
+ }
109
111
}
110
112
}
111
113
return $ children ;
112
114
}
113
-
115
+
114
116
protected function parsePoint ($ xml ) {
115
117
$ coordinates = $ this ->_extractCoordinates ($ xml );
116
118
return new Point ($ coordinates [0 ][0 ],$ coordinates [0 ][1 ]);
117
119
}
118
-
120
+
119
121
protected function parseLineString ($ xml ) {
120
122
$ coordinates = $ this ->_extractCoordinates ($ xml );
121
123
$ point_array = array ();
@@ -124,20 +126,20 @@ protected function parseLineString($xml) {
124
126
}
125
127
return new LineString ($ point_array );
126
128
}
127
-
129
+
128
130
protected function parsePolygon ($ xml ) {
129
131
$ components = array ();
130
-
132
+
131
133
$ outer_boundary_element_a = $ this ->childElements ($ xml , 'outerboundaryis ' );
132
134
$ outer_boundary_element = $ outer_boundary_element_a [0 ];
133
135
$ outer_ring_element_a = $ this ->childElements ($ outer_boundary_element , 'linearring ' );
134
136
$ outer_ring_element = $ outer_ring_element_a [0 ];
135
137
$ components [] = $ this ->parseLineString ($ outer_ring_element );
136
-
138
+
137
139
if (count ($ components ) != 1 ) {
138
140
throw new Exception ("Invalid KML " );
139
141
}
140
-
142
+
141
143
$ inner_boundary_element_a = $ this ->childElements ($ xml , 'innerboundaryis ' );
142
144
if (count ($ inner_boundary_element_a )) {
143
145
foreach ($ inner_boundary_element_a as $ inner_boundary_element ) {
@@ -146,10 +148,10 @@ protected function parsePolygon($xml) {
146
148
}
147
149
}
148
150
}
149
-
151
+
150
152
return new Polygon ($ components );
151
153
}
152
-
154
+
153
155
protected function parseGeometryCollection ($ xml ) {
154
156
$ components = array ();
155
157
$ geom_types = geoPHP::geometryList ();
@@ -162,14 +164,11 @@ protected function parseGeometryCollection($xml) {
162
164
}
163
165
return new GeometryCollection ($ components );
164
166
}
165
-
167
+
166
168
protected function _extractCoordinates ($ xml ) {
167
169
$ coord_elements = $ this ->childElements ($ xml , 'coordinates ' );
168
- if (!count ($ coord_elements )) {
169
- throw new Exception ('Bad KML: Missing coordinate element ' );
170
- }
171
170
$ coordinates = array ();
172
- $ coord_sets = explode (' ' ,$ coord_elements [0 ]->nodeValue );
171
+ $ coord_sets = explode (' ' , $ coord_elements [0 ]->nodeValue );
173
172
foreach ($ coord_sets as $ set_string ) {
174
173
$ set_string = trim ($ set_string );
175
174
if ($ set_string ) {
@@ -179,10 +178,10 @@ protected function _extractCoordinates($xml) {
179
178
}
180
179
}
181
180
}
182
-
181
+
183
182
return $ coordinates ;
184
183
}
185
-
184
+
186
185
private function geometryToKML ($ geom ) {
187
186
$ type = strtolower ($ geom ->getGeomType ());
188
187
switch ($ type ) {
@@ -212,28 +211,38 @@ private function linestringToKML($geom, $type = FALSE) {
212
211
if (!$ type ) {
213
212
$ type = $ geom ->getGeomType ();
214
213
}
215
-
216
- $ str = '< ' .$ this ->nss . $ type .'>< ' .$ this ->nss .'coordinates> ' ;
217
- $ i =0 ;
218
- foreach ($ geom ->getComponents () as $ comp ) {
219
- if ($ i != 0 ) $ str .= ' ' ;
220
- $ str .= $ comp ->getX () .', ' . $ comp ->getY ();
221
- $ i ++;
214
+
215
+ $ str = '< ' .$ this ->nss . $ type .'> ' ;
216
+
217
+ if (!$ geom ->isEmpty ()) {
218
+ $ str .= '< ' .$ this ->nss .'coordinates> ' ;
219
+ $ i =0 ;
220
+ foreach ($ geom ->getComponents () as $ comp ) {
221
+ if ($ i != 0 ) $ str .= ' ' ;
222
+ $ str .= $ comp ->getX () .', ' . $ comp ->getY ();
223
+ $ i ++;
224
+ }
225
+
226
+ $ str .= '</ ' .$ this ->nss .'coordinates> ' ;
222
227
}
223
228
224
- return $ str .'</ ' .$ this ->nss .'coordinates></ ' . $ this ->nss . $ type .'> ' ;
229
+ $ str .= '</ ' . $ this ->nss . $ type .'> ' ;
230
+
231
+ return $ str ;
225
232
}
226
233
227
234
public function polygonToKML ($ geom ) {
228
235
$ components = $ geom ->getComponents ();
229
- $ str = '< ' .$ this ->nss .'outerBoundaryIs> ' . $ this ->linestringToKML ($ components [0 ], 'LinearRing ' ) . '</ ' .$ this ->nss .'outerBoundaryIs> ' ;
230
- foreach (array_slice ($ components , 1 ) as $ comp ) {
231
- $ str .= '< ' .$ this ->nss .'innerBoundaryIs> ' . $ this ->linestringToKML ($ comp ) . '</ ' .$ this ->nss .'innerBoundaryIs> ' ;
236
+ if (!empty ($ components )) {
237
+ $ str = '< ' .$ this ->nss .'outerBoundaryIs> ' . $ this ->linestringToKML ($ components [0 ], 'LinearRing ' ) . '</ ' .$ this ->nss .'outerBoundaryIs> ' ;
238
+ foreach (array_slice ($ components , 1 ) as $ comp ) {
239
+ $ str .= '< ' .$ this ->nss .'innerBoundaryIs> ' . $ this ->linestringToKML ($ comp ) . '</ ' .$ this ->nss .'innerBoundaryIs> ' ;
240
+ }
232
241
}
233
-
242
+
234
243
return '< ' .$ this ->nss .'Polygon> ' . $ str .'</ ' .$ this ->nss .'Polygon> ' ;
235
244
}
236
-
245
+
237
246
public function collectionToKML ($ geom ) {
238
247
$ components = $ geom ->getComponents ();
239
248
$ str = '< ' .$ this ->nss .'MultiGeometry> ' ;
0 commit comments