diff options
Diffstat (limited to 'protected/extensions/egmap/kml/EGMapKMLFeed.php')
| -rw-r--r-- | protected/extensions/egmap/kml/EGMapKMLFeed.php | 394 |
1 files changed, 394 insertions, 0 deletions
diff --git a/protected/extensions/egmap/kml/EGMapKMLFeed.php b/protected/extensions/egmap/kml/EGMapKMLFeed.php new file mode 100644 index 0000000..f787225 --- /dev/null +++ b/protected/extensions/egmap/kml/EGMapKMLFeed.php @@ -0,0 +1,394 @@ +<?php +/** + * + * EGMapKMLFeed Class + * + * KML Feed Creator + * + * @author Antonio Ramirez Cobos + * @link www.ramirezcobos.com + * + * + * @copyright + * + * Copyright (c) 2010 Antonio Ramirez Cobos + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * The above copyright notice and this permission notice shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ +/** + * + * List of currently supported KML tags by Google Maps v3 + * ---------------------------------------------- + * <kml> + * <atom:author> + * <atom:link> + * <atom:name> + * ----------------------------------------------- + * Example + * ------------------------------------------------ + <Document> + <atom:author> + <atom:name>J. K. Rowling</atom:name> + </atom:author> + <atom:link href="http://www.harrypotter.com" /> + <Style id="myStyleId"></Style> + <Placemark></Placemark> + </Document> + ------------------------------------------------ + * <Placemark> + * <styleUrl> + * <name> + * <description> + * <Point> + * <coordinates> + * ------------------------------------------------ + * Example + * ------------------------------------------------ + <Placemark> + <styleUrl>#myIconStyleID</styleUrl> + <name> + <description> + <![CDATA[ + This is an image + <img src="icon.jpg"> + and we have a link http://www.google.com. + ]]> + </description> + <Point> + <coordinates>-90.86948943473118,48.25450093195546</coordinates> + </Point> + </Placemark> + * ------------------------------------------------ + * <Style> + * <IconStyle id="myIconStyleID> + * <Icon> + * <PolyStyle id="myPolyStyleID"> + * <color> + * <colorMode> + * <LineStyle> + * <color> + * <width> + * + * + * ------------------------------------------------ + * Examples + * ------------------------------------------------ + <Document> + <Style id="restaurantStyle"> + <IconStyle id="restuarantIcon"> + <Icon> + <href>http://maps.google.com/mapfiles/kml/pal2/icon63.png</href> + </Icon> + </IconStyle> + </Style> + ------------------------------------------------ + <Style id="examplePolyStyle"> + <PolyStyle> + <color>ff0000cc</color> + <colorMode>random</colorMode> + </PolyStyle> + </Style> + ------------------------------------------------ + <Style id="linestyleExample"> + <LineStyle> + <color>7f0000ff</color> + <width>4</width> + </LineStyle> + </Style> + </Document> + * ------------------------------------------------ + * <LatLonBox> + * <north> + * <south> + * <east> + * <west> + * ------------------------------------------------ + * Example + * ------------------------------------------------ + <Document> + <LatLonBox> + <north>48.25475939255556</north> + <south>48.25207367852141</south> + <east>-90.86591508839973</east> + <west>-90.8714285289695</west> + </LatLonBox> + </Document> + ------------------------------------------------ + * <NetworkLink> + * <Link> + * <refreshMode> + * <refreshInterval> + * <viewRefreshTime> + * ------------------------------------------------ + * Example + * ------------------------------------------------ + <Document> + <NetworkLink> + <name>NE US Radar</name> + <Link> + <href>http://www.example.com/geotiff/NE/MergedReflectivityQComposite.kml</href> + <refreshMode>onInterval</refreshMode> // headers HTTP only compatible with mode "onExpire" + <refreshInterval>30</refreshInterval> + <viewRefreshMode>onStop</viewRefreshMode> + <viewRefreshTime>7</viewRefreshTime> + </Link> + </NetworkLink> + </Document> + * ------------------------------------------------ + * <Polygon> + * <outerBoundaryIs> + * <LinearRing> + * <coordinates> + * <LineString> + * <coordinates> + * ------------------------------------------------ + * Example + * ------------------------------------------------ + <Placemark> + <Polygon> + <innerBoundaryIs> // only supported here + <LinearRing> + <coordinates> + -122.366212,37.818977,30 + -122.365424,37.819294,30 + </coordinates> + </LinearRing> + </innerBoundaryIs> + </Polygon> + </Placemark> + <Placemark> + <name>unextruded</name> + <LineString> + <coordinates> + -122.364383,37.824664,0 -122.364152,37.824322,0 + </coordinates> + </LineString> + </Placemark> + ------------------------------------------------ + * Other supported tags by Google Maps v3 + * <range> + * <ScreenOverlay> + * <size> + * <Snippet> + * <value> + * <longitude> + * <open> + * <outline> + * <expires> + * <fill> + * <heading> + * <hotSpot> + * <latitude> + */ +class EGMapKMLFeed { + /** + * + * Holds all tags on the feed + * @var unknown_type + */ + protected $elements; + + const STYLE_ICON = 'Icon'; // when using addStyle Array it specifies is an IconStyle + const STYLE_LINE = 'Line'; // when using addStyle Array it specifies is an LineStyle + const STYLE_POLY = 'Poly'; // when using addStyle Array it specifies is an PolyStyle + /** + * + * constructor + */ + function __construct(){ + $this->elements = new CMap(); + } + /** + * + * ATOM style author + * @param string $name + */ + public function setAuthor( $name ){ + if( null === $this->elements->itemAt('head') ) + $this->elements->add('head', new CMap() ); + $item = '<atom:author><atom:name>'.$name.'</atom:name></atom:author>'; + + $this->elements->itemAt('head')->add('author', $item); + + } + /** + * + * ATOM style link + * @param string $url + */ + public function setLink( $url ){ + if( null === $this->elements->itemAt('head') ) + $this->elements->add('head', new CMap() ); + $validator = new CUrlValidator(); + if(!$validator->validateValue($url)) + throw new CException( Yii::t('EGMap', 'EGMapKMLFeed.setLink Url does not seem to valid') ); + $item = '<atom:link href="'.$url.'" />'; + $this->elements->itemAt('head')->add('link', $item); + } + /** + * + * Adding an externally created Tag at the end of its 'body' section + * Note: this method does not validates the tag + * @param EGMapKMLNode $tag + * @return string id of the inserted Tag + */ + public function addTag( EGMapKMLNode $tag ){ + if( null === $this->elements->itemAt('body') ) + $this->elements->add('body', new CMap() ); + + $name = uniqid(); + + $this->elements->itemAt('body')->add(uniqid(), $tag->toXML()); + + return $name; + } + /** + * + * Removes inserted tag name from specific section + * sections can be head, body, styles, and placemark + * @param string $tagName to be removed + * @param string $section where to remove the tag + */ + public function removeTag( $tagName, $section ){ + foreach($this->elements as $map) + { + if($map->itemAt($section)){ + $map->itemAt($section)->remove($tagName); + return true; + } + } + return false; + } + /** + * + * This method is to add style tags as arrays + * the style nodes are represented as the following: + * <pre> + * // Icon + * $nodes = array( 'href'=>'http://url'); + * // Line + * $nodes = array( 'color'=>'#FFAA00','width'=>2); + * // Polyline + * $nodes = array( 'color'=>'#FFAA00','colorMode'=>'random' ); + * </pre> + * @param string $styleId id of the style + * @param string $styleType the type of the style + * @param array $nodes the tags to insert + */ + public function addStyleArray( $styleId, $styleType = self::STYLE_ICON, $nodes = array() ){ + $item = '<Style id="'.$styleId.'">'; + switch ($styleType){ + case self::STYLE_ICON: + case self::STYLE_LINE: + case self::STYLE_POLY: + $item .= CHtml::openTag($styleType.'Style'); + break; + default: + throw new CException( Yii::t('EGMap','KML Style not supported') ); + } + $item .= $this->batchNodeCreate($nodes); + + $item .= CHtml::closeTag($styleType.'Style'); + $item .= '</Style>'; + + if( null === $this->elements->itemAt('styles') ) + $this->elements->add( 'styles', new CMap() ); + + $this->elements->itemAt('styles')->add( $styleId, $item ); + } + /** + * Adds a placemark on array structure + * Example: + * <pre> + * $nodes = array( + * 'name'=>array('content'=>'testing'), + * 'description'=>array('content'=>'This marker has <b>HTML</b>'), + * 'styleUrl'=>array('content'=>'#style2'), + * 'Point'=>array('children'=>array( + * 'coordinates'=>array('content'=>'2.9087440013885635,39.719588117933185,0')))); + * + * $kml->addPlacemark($nodes); + * </pre> + * @param array $nodes the tags to insert + */ + public function addPlacemarkArray( $nodes = array() ){ + $item = '<Placemark>'; + + $item .= $this->batchNodeCreate($nodes); + + $item .= '</Placemark>'; + + if( null === $this->elements->itemAt('body') ) + $this->elements->add( 'body', new CMap() ); + + $name = uniqid(); + + $this->elements->itemAt('body')->add( $name, $item ); + + return $name; + + } + /** + * + * Converts array given tags to its XML representation + * Note: It does not check for correct array structure + * + * @param array $tags + */ + public function batchNodeCreate( $tags ){ + $result = ''; + if(is_array( $tags) ){ + foreach($tags as $tag=>$el){ + $result .= CHtml::openTag($tag, (isset($el['attributes']) && is_array($el['attributes'])? $el['attributes']:array())); + $result .= isset($el['content'])? ($tag=='description'? '<![CDATA['. $el['content'].']]>': $el['content']) : ''; + $result .= isset($el['children']) && is_array($el['children'])? $this->batchNodeCreate($el['children']) : ''; + $result .= CHtml::closeTag($tag); + } + } + return $result; + } + /** + * + * Generates the feed + */ + public function generateFeed( ){ + // you can choose between the both, as both of them work correctly + // Google Earth MIME/TYPE + // header('Content-type: application/vnd.google-earth.kml+xml'); + header("Content-type: text/xml"); + + echo '<kml xmlns="http://earth.google.com/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">'; + echo '<Document>'; + $this->renderItems(array('head', 'body','styles','placemarks')); + echo '</Document>'; + echo '</kml>'; + } + /** + * + * Render tags by sections + * @param array | string sections to render $sections + */ + public function renderItems( $sections ){ + + if(!is_array($sections)) $sections = array( $sections ); + + foreach( $sections as $section ){ + if(null === $this->elements->itemAt($section)) continue; + + foreach($this->elements->itemAt($section) as $tag) + echo $tag; + } + } +} |
