<?
/**
* This notice must be untouched at all times.
*
* The latest version is available at
* http://sourceforge.net/projects/appformap/
* @copyright Martin Høgh. All rights reserved.
* @author Martin Høgh <hide@address.com>
* @version 0.6
* @package phpgeometry_class.php
* @abstract Php class library. Creates geometry object from Well-known Text Representation or gml.
* The class's have operations for manipulating the geometry and getting various types of information.
*/
class geometryfactory
{
/**
* @return Geometry object
* @param string $wkt test
* @param int $srid
* @desc Creates a new geometry object from a wkt string
*/
function createGeometry($wkt,$srid=NULL)//creates a new geometry object. Factory function
{
$wkt = str_replace(", ",",",$wkt);// replace " ," with ","
preg_match_all("/[a-z]*[A-Z]*/",$wkt,$__typeArray);//Match the type of the geometry
$__type=$__typeArray[0][0];
switch ($__type)
{
case "MULTIPOLYGON":
$geometryObject=new multipolygon($wkt,$srid);
break;
case "MULTILINESTRING":
$geometryObject=new multilinestring($wkt,$srid);
break;
case "MULTIPOINT":
$geometryObject=new multipoint($wkt,$srid);
break;
case "POINT":
$geometryObject=new _point($wkt,$srid); //point is a key word
break;
case "LINESTRING":
$geometryObject=new linestring($wkt,$srid);
break;
case "POLYGON":
$geometryObject=new polygon($wkt,$srid);
break;
}
return ($geometryObject);
}
function createGeometryCollection($wktArray)
{
$geometryCollection=new geometryCollection($wktArray);
return($geometryCollection);
}
function deconstructionOfWKT() // Take a WKT string and returns a array with coords(string) for shapes. Called from a child object
{
preg_match_all("/[^a-z|(*]*[0-9]/",$this->wkt,$__wktArray); // regex is used exstract coordinates
$wktArray=$__wktArray[0];
if ($this->getGeomType()=="MULTIPOLYGON" || $this->getGeomType()=="POLYGON")
{
preg_match_all("/[^a-z|)]*[0-9]/",$this->wkt,$__array); // regex is used to find island shapes
for ($__i = 0; $__i < (sizeof($__array[0])); $__i ++)
{
if (substr($__array[0][$__i], 0 ,2 )==",(" && substr($__array[0][$__i], 2 ,1 )!="(" )
{
$this->isIsland[$__i]=true;
}
else
{
$this->isIsland[$__i]=false;
}
}
}
if ($this->getGeomType()=="MULTIPOINT")// if multipoint when split the string again
{
preg_match_all("/[^a-z|,]*[0-9]/",$wktArray[0],$__array); // regex is used exstract coordinates
$wktArray=$__array[0];
}
return ($wktArray);
}
function snapCoords($coordStr,$snapTolerance,$snapLayerStr,$shapeArray=array())
{
$__snap=false;
$__newCoordStr = explode(",", $coordStr);
$__snapLayerArray = explode(",", $snapLayerStr);
$i = 0;
foreach($__newCoordStr as $__v)// each point from the coordStr string is looped
{
$__snapToleranceTmp=$snapTolerance;// asign the value to a tmp var, so it can be restored
$__oneCoord = explode(" ", $__v);
$__oneCoordTmp = explode(" ", $__v);// save the original coord in a tmp for line snap
$u = 0;
// first check for vertex snap
if (sizeof($__snapLayerArray))
{
foreach($__snapLayerArray as $__u)// each possible pointsnap point is evaluated
{
$__snapLayerCoord = explode(" ", $__u);
$diffX = $__snapLayerCoord[0] - $__oneCoord[0];
$diffY = $__snapLayerCoord[1] - $__oneCoord[1];
$diff = sqrt(pow($diffX, 2) + pow($diffY, 2));
//calculation of distance between the two point
if ($diff <= $__snapToleranceTmp)// true if in snap tolerance
{
//echo "snap"."<br>";
$__snapToleranceTmp = $diff;
//decrease of snap tolerance, so only the nearest point is used
$__snap = true; // point is snapped
$__newSnapLayerCoord[0] = $__snapLayerCoord[0];
$__newSnapLayerCoord[1] = $__snapLayerCoord[1];
}
}
}
if ($__snap == true) //true if evaluated point is snapped
{
$__oneCoord[0] = $__newSnapLayerCoord[0];
//New value of digi point
$__oneCoord[1] = $__newSnapLayerCoord[1];
$__snap = false; // so the next digi point is not snapped
}
// second check for line snap
if (sizeof($shapeArray))
{
foreach($shapeArray as $__u)// each possible line snap is evaluated
{
//echo "<script>alert('$__u');</script>";
$__lineSegments = explode(",", $__u);
for ($__i = 0; $__i < (sizeof($__lineSegments)-1); $__i ++)
{
$__l1=explode(" ",$__lineSegments[$__i]);// first coord in line segment
$__l2=explode(" ",$__lineSegments[$__i+1]);// second coord in line segment
$diff=$this->distancePointToLine ($__oneCoordTmp,$__l1,$__l2);
//echo "<script>alert('tmp ".$__snapToleranceTmp."');</script>";
//echo "<script>alert('lineafstand ".$diff[0]."');</script>";
if ($diff[0] < $__snapToleranceTmp && $diff[0]!=FALSE)// true if in snap tolerance
{
//echo "<script>alert('".$diff[0]."');</script>"."<br>";
$__snapToleranceTmp = $diff[0];
//decrease of snap tolerance, so only the nearest point is used
$__snap = true; // point is snapped
$newCoord=$diff[1];
$__newSnapLayerCoord[0] = $newCoord[0];
$__newSnapLayerCoord[1] = $newCoord[1];
}
}
}
if ($__snap == true) //true if evaluated point is snapped
{
$__oneCoord[0] = $__newSnapLayerCoord[0];
//New value of digi point
$__oneCoord[1] = $__newSnapLayerCoord[1];
$__snap = false; // so the next digi point is not snapped
}
}
$__newCoordStr[$i] = implode(" ", $__oneCoord);
$i ++;
}
$coordStr = implode(",", $__newCoordStr);
return ($coordStr);
}
function getVertices()//get a string with all vertices of geometry
{
$verticeStr="";
foreach($this->shapeArray as $__value)
{
$verticeStr=$verticeStr.$__value.",";
}
// remove the last comma
$verticeStr=substr($verticeStr, 0, strlen($verticeStr) - 1);
return($verticeStr);
}
function updateShape($coorStr,$shapeId)// updates the geometry on shape level. Takes a string with coords and a shape id
{
for ($__i = 0; $__i < sizeof($this->shapeArray); $__i ++)
{
if ($__i == $shapeId) {$this->shapeArray[$__i] = $coorStr;$__check=true;}
}
//echo "<script>alert(\"".$coorStr."\")</script>";
if (!$__check) {$this->shapeArray[$this->getNumOfShapes()] = $coorStr;}
$this->construction();
}
function snapShape($shapeId,$snapTolerance,$snapLayerStr,$shapeArray=array())// snaps one shape with shapeId of multifeature
{
$__newShape=$this->snapCoords($this->shapeArray[$shapeId],$snapTolerance,$snapLayerStr,$shapeArray);
$this->updateShape($__newShape,$shapeId);
}
function snapAllShapes($snapTolerance,$snapLayerStr,$shapeArray=array())// snaps all shapes of multifeature or just like snap the hole geometry
{
foreach($this->shapeArray as $__key => $__shape)
{
$__newShape=$this->snapCoords($this->shapeArray[$__key],$snapTolerance,$snapLayerStr,$shapeArray);
$this->updateShape($__newShape,$__key);
}
}
function getWKT()
{
return ($this->wkt);
}
function getGML()
{
return ($this->toGML());
}
function getShapeArray()
{
return ($this->shapeArray);
}
function getGeomType()
{
return ($this->geomType[$count]);
}
function getNumOfShapes()
{
return sizeOf($this->getShapeArray());
}
function writeTag($type,$ns,$tag,$atts,$ind,$n)
{
$_str="";
global $depth;
if($ind!=False)
{
for($i=0;$i<$depth;$i++)
{
$_str=$_str." ";
}
}
if($ns!=null){
$tag=$ns.":".$tag;
}
$_str.="<";
if($type=="close"){
$_str=$_str."/";
}
$_str=$_str.$tag;
if(!empty($atts)){
foreach ($atts as $key => $value) {
$_str=$_str.' '.$key.'="'.$value.'"';
}
}
if($type=="selfclose"){
$_str=$_str."/";
}
$_str=$_str.">";
if($n==True){
$_str=$_str."\n";
}
return($_str);
}
/**
* @return array
* @param array $p
* @param array $l1
* @param array $l2
* @desc Caculate the distance between a point and a line with two points and the point of perpendicular projection
*/
function distancePointToLine ($p,$l1,$l2)
{
$u=((($l2[0]-$l1[0])*($l1[1]-$p[1]))-(($l1[0]-$p[0])*($l2[1]-$l1[1])));
$l=sqrt(pow(($l2[0]-$l1[0]),2)+pow(($l2[1]-$l1[1]),2));
if ($l) $a=($u/$l);
if ($a<0) $a=$a*-1;
$diffX = $l1[0] - $l2[0];
$diffY = $l1[1] - $l2[1];
$l = sqrt(pow($diffX, 2) + pow($diffY, 2));
if ($l) $r=(($p[0]-$l1[0])*($l2[0]-$l1[0])+($p[1]-$l1[1])*($l2[1]-$l1[1]))/pow($l,2);
$newCoord[0]=$l1[0]+$r*($l2[0]-$l1[0]);
$newCoord[1]=$l1[1]+$r*($l2[1]-$l1[1]);
//Set the bounding box of line segment
if ($l1[0]>=$l2[0])
{
$__maxX=$l1[0];
$__minX=$l2[0];
}
else
{
$__maxX=$l2[0];
$__minX=$l1[0];
}
if ($l1[1]>=$l2[1])
{
$__maxY=$l1[1];
$__minY=$l2[1];
}
else
{
$__maxY=$l2[1];
$__minY=$l1[1];
}
// If the point of perpendicular projection is outside bbox then set distance to FALSE
if ($newCoord[0]>$__maxX || $newCoord[0]<$__minX || $newCoord[1]>$__maxY || $newCoord[1]<$__minY)
{
$a=FALSE;
//echo "<script>alert('outside');</script>";
}
return (array($a,$newCoord));
}
function convertPoint($geom,$hasSrid=TRUE){
global $depth;
if(($hasSrid) && ($this->srid!=NULL)) $srid=array("srsName"=>$this->srid);
else $srid=NULL;
$_str="";
$_str=$_str.$this->writeTag("open","gml","Point",$srid,True,True);
$depth++;
$_str=$_str.$this->writeTag("open","gml","coordinates",NULL,True,False);
$_str=$_str.$this->convertCoordinatesToGML($geom);
$_str=$_str.$this->writeTag("close","gml","coordinates",Null,False,True);
$depth--;
$_str=$_str.$this->writeTag("close","gml","Point",Null,True,True);
return($_str);
}
function convertLineString($geom,$hasSrid=TRUE)
{
global $depth;
if(($hasSrid) && ($this->srid!=NULL)) $srid=array("srsName"=>$this->srid);
else $srid=NULL;
$_str="";
$_str.=$this->writeTag("open","gml","LineString",$srid,True,True);
$depth++;
$_str.=$this->writeTag("open","gml","coordinates",Null,True,False);
$_str.=$this->convertCoordinatesToGML($geom);
$_str.=$this->writeTag("close","gml","coordinates",Null,False,True);
$depth--;
$_str.=$this->writeTag("close","gml","LineString",Null,True,True);
return($_str);
}
/**
* @return unknown
* @param unknown $rings
* @param unknown $hasSrid
* @desc Enter description here...
*/
function convertPolygon($rings,$hasSrid=TRUE)
{
global $depth;
if(($hasSrid) && ($this->srid!=NULL)) $srid=array("srsName"=>$this->srid);
else $srid=NULL;
$_str="";
$_str=$_str.$this->writeTag("open","gml","Polygon",$srid,True,True);
$depth++;
$pass=0;
foreach ($rings as $ring) {
if($pass==0){
$boundTag="outer";
}
else{
$boundTag="inner";
}
$_str=$_str.$this->writeTag("open","gml","".$boundTag."BoundaryIs",Null,True,True);
$depth++;
$_str=$_str.$this->writeTag("open","gml","LinearRing",Null,True,True);
$depth++;
$_str=$_str.$this->writeTag("open","gml","coordinates",Null,True,False);
$_str=$_str.$this->convertCoordinatesToGML($ring);
$_str=$_str.$this->writeTag("close","gml","coordinates",Null,False,True);
$depth--;
$_str=$_str.$this->writeTag("close","gml","LinearRing",Null,True,True);
$depth--;
$_str=$_str.$this->writeTag("close","gml","".$boundTag."BoundaryIs",Null,True,True);
$pass++;
}
$depth--;
$_str=$_str.$this->writeTag("close","gml","Polygon",Null,True,True);
return($_str);
}
function convertCoordinatesToGML($_str)
{
$_str = str_replace(" ","&",$_str);
$_str = str_replace(","," ",$_str);
$_str = str_replace("&",",",$_str);
$_str = str_replace("(","",$_str);
$_str = str_replace(")","",$_str);
return ($_str);
}
}
class _point extends geometryfactory
{
var $wkt;
var $shapeArray;
var $geomType;
function _point($wkt,$srid)// constructor. wkt is set
{
$this->wkt=$wkt;
$this->srid=$srid;
$this->geomType[$count]='POINT';
$this->shapeArray=parent::deconstructionOfWKT($this->wkt);
}
function construction()// puts the deconstructed wkt together again and sets the wkt
{
$__newWkt = $this->geomType[$count]."(".$this->shapeArray[0].")";
$this->wkt=$__newWkt;
}
function toGML()
{
global $depth;
$_str="";
$_str.=$this-> convertPoint($this->shapeArray[0]);
return ($_str);
}
}
class linestring extends geometryfactory
{
/**
* @var string
*/
var $wkt;
/**
* @var array
*/
var $shapeArray;
var $geomType;
function linestring($wkt,$srid)// constructor. wkt is set
{
$this->wkt=$wkt;
$this->srid=$srid;
$this->geomType[$count]='LINESTRING';
$this->shapeArray=parent::deconstructionOfWKT($this->wkt);
}
function construction()// puts the deconstructed wkt together again and sets the wkt
{
$__newWkt = $this->geomType[$count]."(".$this->shapeArray[0].")";
$this->wkt=$__newWkt;
}
function toGML()
{
global $depth;
$_str="";
$_str.=$this-> convertLineString($this->shapeArray[0]);
return ($_str);
}
}
class polygon extends geometryfactory
{
var $wkt;
var $shapeArray;
var $geomType;
function polygon($wkt,$srid)// constructor. wkt is set
{
$this->wkt=$wkt;
$this->srid=$srid;
$this->geomType[$count]='POLYGON';
$this->shapeArray=parent::deconstructionOfWKT($this->wkt);
}
function construction()// puts the deconstructed wkt together again and sets the wkt
{$__newWkt = $this->geomType[$count]."(";
for ($__i = 0; $__i < (sizeof($this->shapeArray)); $__i ++)
{
$__wktArray[$__i] = "(".$this->shapeArray[$__i].")";
}
$__newWkt = $__newWkt.implode(",", $__wktArray);
$__newWkt = $__newWkt.")";
$this->wkt=$__newWkt;
}
function toGML()
{
global $depth;
$_str="";
$_str.=$this-> convertPolygon($this->shapeArray);
return ($_str);
}
}
class multipoint extends geometryfactory
{
var $wkt;
var $shapeArray;
var $geomType;
function multipoint($wkt,$srid)// constructor. wkt is set
{
$this->wkt=$wkt;
$this->srid=$srid;
$this->geomType[$count]='MULTIPOINT';
$this->shapeArray=parent::deconstructionOfWKT($this->wkt);
}
function construction()// puts the deconstructed wkt together again and sets the wkt
{
$__newWkt = $this->geomType[$count]."(";
for ($__i = 0; $__i < (sizeof($this->shapeArray)); $__i ++)
{
$__wktArray[$__i] = $this->shapeArray[$__i];
}
$__newWkt = $__newWkt.implode(",", $__wktArray);
$__newWkt = $__newWkt.")";
$this->wkt=$__newWkt;
}
function toGML()
{
global $depth;
if ($this->srid) $srid=array("srsName"=>$this->srid);
else $srid=NULL;
$_str="";
$_str.=$this->writeTag("open","gml","MultiPoint",$srid,True,True);
$depth++;
for ($__i = 0; $__i < (sizeof($this->shapeArray)); $__i ++)
{
$_str.=$this->writeTag("open","gml","PointMember",Null,True,True);
$depth++;
$_str.=$this->convertPoint($this->shapeArray[$__i],FALSE);
$depth--;
$_str.=$this->writeTag("close","gml","PointMember",Null,True,True);
}
$depth--;
$_str.=$this->writeTag("close","gml","MultiPoint",Null,True,True);
return ($_str);
}
}
class multilinestring extends geometryfactory
{
var $wkt;
var $shapeArray;
var $geomType;
function multilinestring($wkt)// constructor. wkt is set
{
$this->wkt=$wkt;
$this->geomType[$count]='MULTILINESTRING';
$this->shapeArray=parent::deconstructionOfWKT($this->wkt);
}
function construction()// puts the deconstructed wkt together again and sets the wkt
{
$__newWkt = $this->geomType[$count]."(";
for ($__i = 0; $__i < (sizeof($this->shapeArray)); $__i ++)
{
$__wktArray[$__i] = "(".$this->shapeArray[$__i].")";
}
$__newWkt = $__newWkt.implode(",", $__wktArray);
$__newWkt = $__newWkt.")";
$this->wkt=$__newWkt;
}
function toGML()
{
global $depth;
if ($this->srid) $srid=array("srsName"=>$this->srid);
else $srid=NULL;
$_str="";
$_str.=$this->writeTag("open","gml","MultiLineString",$srid,True,True);
$depth++;
for ($__i = 0; $__i < (sizeof($this->shapeArray)); $__i ++)
{
$_str.=$this->writeTag("open","gml","lineStringMember",Null,True,True);
$depth++;
$_str.=$this->convertLineString($this->shapeArray[$__i],FALSE);
$depth--;
$_str.=$this->writeTag("close","gml","lineStringMember",Null,True,True);
}
$depth--;
$_str.=$this->writeTag("close","gml","MultiLineString",Null,True,True);
return ($_str);
}
}
class multipolygon extends geometryfactory
{
var $wkt;
var $shapeArray;
var $geomType;
var $isIsland;
var $gml;
function multipolygon($wkt,$srid)// constructor. wkt is set
{
$this->wkt=$wkt;
$this->srid=$srid;
$this->geomType[$count]='MULTIPOLYGON';
$this->shapeArray=parent::deconstructionOfWKT($this->wkt);
}
function construction()// puts the deconstructed wkt together again and sets the wkt
{
$__newWkt = $this->geomType[$count]."(";
for ($__i = 0; $__i < (sizeof($this->shapeArray)); $__i ++)
{
switch ($this->isIsland[$__i])//check if a shape is an island of another
{
case false:
if ($this->isIsland[$__i+1]==true)// what is the next one?
$__wktArray[$__i] = "((".$this->shapeArray[$__i].")";
else
$__wktArray[$__i] = "((".$this->shapeArray[$__i]."))";
break;
case true:
if ($this->isIsland[$__i+1]==true)
$__wktArray[$__i] = "(".$this->shapeArray[$__i].")";
else
$__wktArray[$__i] = "(".$this->shapeArray[$__i]."))";
break;
}
}
$__newWkt = $__newWkt.implode(",", $__wktArray);
$__newWkt = $__newWkt.")";
$this->wkt=$__newWkt;
}
function toGML()
{
global $depth;
if ($this->srid) $srid=array("srsName"=>$this->srid);
else $srid=NULL;
$_str="";
$_polys=array();
$__i=0;
while($this->shapeArray[$__i])
{
if ($this->isIsland[$__i+1])
{
$_rings=array($this->shapeArray[$__i]);
while ($this->isIsland[$__i+1])
{
array_push($_rings,$this->shapeArray[$__i+1]);
$__i++;
}
array_push($_polys,$_rings);
$__i++;
}
else
{
array_push($_polys,array($this->shapeArray[$__i]));
$__i++;
}
}
$_str=$_str.$this->writeTag("open","gml","MultiPolygon",$srid,True,True);
$depth++;
foreach ($_polys as $__array)
{
$_str=$_str.$this->writeTag("open","gml","polygonMember",Null,True,True);
$depth++;
$_str=$_str.$this->convertPolygon($__array,FALSE);
$depth--;
$_str=$_str.$this->writeTag("close","gml","polygonMember",Null,True,True);
}
$depth--;
$_str=$_str.$this->writeTag("close","gml","MultiPolygon",Null,True,True);
return ($_str);
}
}
class geometryCollection extends geometryfactory
{
var $geometryArray;
function geometryCollection($wktArray)
{
foreach($wktArray as $__key => $__value)
{
$this->geometryArray[$__key]=parent::createGeometry($__value);
}
}
function getVertices()
{
foreach($this->geometryArray as $__geometry)
{
$__verticeStr="";
foreach($__geometry->getShapeArray() as $__value)
{
$__verticeStr=$__verticeStr.$__value.",";
}
$verticeStr=$verticeStr.$__verticeStr;
}
// remove the last comma
$verticeStr=substr($verticeStr, 0, strlen($verticeStr) - 1);
return($verticeStr);
}
function getShapes()
{
$__shapeArray=array();
foreach($this->geometryArray as $__geometry)
{
foreach($__geometry->getShapeArray() as $__value)
{
array_push($__shapeArray,$__value);
}
}
$shapeArray=$__shapeArray;
return($shapeArray);
}
function getGeometryArray()
{
return($this->geometryArray);
}
}
class gmlConverter
{
var $parser;
var $geomType;
var $wkt;
var $isIsland;
var $wktCoords;
var $isPreviousIsland;
var $splitTag;
var $srid;
function gmlConverter()
{
$this->xml();
}
function xml()
{
$this -> parser = xml_parser_create();
xml_set_object($this -> parser, & $this);
xml_set_element_handler($this -> parser, "startElement", "endElement");
xml_set_character_data_handler($this -> parser, "characterData");
}
/**
* @return array
* @param string $gml
* @param string $splitTag
* @desc Enter description here...
*/
function gmlToWKT($gml,$splitTag="GML:FEATUREMEMBER")
{
global $count;
// Clen up messy gml. Remove spaces and tabs.
$gml=ereg_replace("\t", "",$gml);
$gml=ereg_replace("\r", "",$gml);
$gml=ereg_replace("\n", "",$gml);
$gml=ereg_replace(">[[:space:]]+",">",$gml);
$gml=ereg_replace("[[:space:]]+<", "<",$gml);
// echo "<!-- gml /".$gml."-->";
$this->splitTag=strtoupper($splitTag);
$count=0;
$currentTag = "";
xml_parse($this -> parser, $gml);
// clean up
xml_parser_free($this -> parser);
for ($__i = 0; $__i < sizeof($this->wktCoords); $__i ++)
{
if ($this->geomType[$__i]=="MULTIPOINT" || $this->geomType[$__i]=="MULTIPOLYGON" || $this->geomType[$__i]=="MULTILINESTRING") $this->wktCoords[$__i]=substr($this->wktCoords[$__i], 0, strlen($this->wktCoords[$__i]) - 1);
$this->wktCoords[$__i]=$this->geomType[$__i]."(".$this->wktCoords[$__i].")";
}
return(array($this->wktCoords,$this->srid));
}
function startElement($parser, $name, $attrs)
{
global $currentTag; //used by function characterData when parsing xml data
global $count;
$currentTag = $name;
//echo $count;
if ($attrs['SRSNAME']!="") $this->srid[$count]=$this->parseEpsgCode($attrs['SRSNAME']);
switch ($currentTag)
{
case "GML:POINT" :
$this->geomType[$count]="POINT";
break;
case "GML:LINESTRING" :
$this->geomType[$count]="LINESTRING";
break;
case "GML:POLYGON" :
$this->geomType[$count]="POLYGON";
break;
case "GML:MULTIPOINT" :
$this->geomType[$count]="MULTIPOINT";
break;
case "GML:MULTILINESTRING" :
$this->geomType[$count]="MULTILINESTRING";
break;
case "GML:MULTIPOLYGON" :
$this->geomType[$count]="MULTIPOLYGON";
break;
case "GML:MULTIGEOMETRY" :
$this->geomType[$count]="MULTIGEOMETRY";
break;
case "GML:POLYGONMEMBER":
$this->wktCoords[$count].="(";
break;
case "GML:LINESTRINGMEMBER":
$this->wktCoords[$count].="(";
break;
case "GML:INNERBOUNDARYIS";
$this->isIsland=true;
break;
case "GML:OUTERBOUNDARYIS";
$this->isIsland=false;
break;
}
}
function endElement($parser, $name)
{
global $currentTag;
global $count;
$currentTag=$name;
//echo $currentTag;
switch ($currentTag)
{
case "GML:POLYGONMEMBER":
$this->wktCoords[$count].="),";
break;
case "GML:LINESTRINGMEMBER":
$this->wktCoords[$count].="),";
break;
case "GML:POINTMEMBER":
$this->wktCoords[$count].=",";
break;
//Read the last tag and set the main feature geometry type.
case "GML:POINT" :
$this->geomType[$count]="POINT";
break;
case "GML:LINESTRING" :
$this->geomType[$count]="LINESTRING";
break;
case "GML:POLYGON" :
$this->geomType[$count]="POLYGON";
break;
case "GML:MULTIPOINT" :
$this->geomType[$count]="MULTIPOINT";
break;
case "GML:MULTILINESTRING" :
$this->geomType[$count]="MULTILINESTRING";
break;
case "GML:MULTIPOLYGON" :
$this->geomType[$count]="MULTIPOLYGON";
break;
case "GML:MULTIGEOMETRY" :
$this->geomType[$count]="MULTIGEOMETRY";
break;
case $this->splitTag :
$count++;
break;
}
$currentTag = null;
}
function characterData($parser, $data)
{
global $concatCoords;
global $currentTag;
global $count;
// echo $this->geomType[$count];
//echo $currentTag;
switch ($currentTag)
{
case "GML:COORDINATES" :
$concatCoords.=$data; // concat the data in case of the 1024 char limit is exceeded
if (strlen($data)<1024)// To defeat the 1024 char limit on the sax parser
{
if ($this->geomType[$count]=="POINT")
{
$this->wktCoords[$count].=$this->convertCoordinatesToWKT($concatCoords);
}
else if ($this->geomType[$count]=="LINESTRING")
{
$this->wktCoords[$count].=$this->convertCoordinatesToWKT($concatCoords);
}
else if ($this->geomType[$count]=="POLYGON")
{
if ($this->isIsland==true) $this->wktCoords[$count].=",";
$this->wktCoords[$count].="(".$this->convertCoordinatesToWKT($concatCoords).")";
}
$concatCoords="";
}
break;
case "PROPERTYNAME";
$this->filterPropertyName[$data]=$count;
break;
}
}
function convertCoordinatesToWKT($_str)
{
$_str = str_replace(" ","&",$_str);
$_str = str_replace(","," ",$_str);
$_str = str_replace("&",",",$_str);
return ($_str);
}
function parseEpsgCode($epsg)
{
if (strtoupper(substr($epsg, 0, 5)=="EPSG:")) $epsg=substr($epsg, 5,strlen($epsg));
return $epsg;
}
}
?>