summaryrefslogtreecommitdiff
path: root/protected/extensions/egmap/kml/EGMapKMLFeed.php
diff options
context:
space:
mode:
Diffstat (limited to 'protected/extensions/egmap/kml/EGMapKMLFeed.php')
-rw-r--r--protected/extensions/egmap/kml/EGMapKMLFeed.php394
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;
+ }
+ }
+}