<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>What was it again?</title>
	<atom:link href="http://whatwasitagain.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://whatwasitagain.wordpress.com</link>
	<description>More a notebook than a blog..</description>
	<lastBuildDate>Sat, 21 Jan 2012 17:38:50 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='whatwasitagain.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>What was it again?</title>
		<link>http://whatwasitagain.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://whatwasitagain.wordpress.com/osd.xml" title="What was it again?" />
	<atom:link rel='hub' href='http://whatwasitagain.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Ways to make feature tile layers interactive</title>
		<link>http://whatwasitagain.wordpress.com/2011/06/12/interactive-feature-tile-layers/</link>
		<comments>http://whatwasitagain.wordpress.com/2011/06/12/interactive-feature-tile-layers/#comments</comments>
		<pubDate>Sun, 12 Jun 2011 08:27:27 +0000</pubDate>
		<dc:creator>whatwasitagain</dc:creator>
				<category><![CDATA[Geo]]></category>
		<category><![CDATA[google fusion tables]]></category>
		<category><![CDATA[openlayers]]></category>
		<category><![CDATA[tilemill]]></category>
		<category><![CDATA[utfgrid]]></category>
		<category><![CDATA[wmfts]]></category>

		<guid isPermaLink="false">http://whatwasitagain.wordpress.com/?p=125</guid>
		<description><![CDATA[Most maps do not just consist of a static base map. Usually you want to visualize some additional data on top of that base map. This additional data, for example POIs, tracks or boundaries, should be presented in a way that the user can interact with the data. If your data does not exceed a [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=whatwasitagain.wordpress.com&amp;blog=4842555&amp;post=125&amp;subd=whatwasitagain&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Most maps do not just consist of a static base map. Usually you want to visualize some additional data on top of that base map. This additional data, for example POIs, tracks or boundaries, should be presented in a way that the user can interact with the data.</p>
<p>If your data does not exceed a certain size, the browser does a great job in rendering the data and taking care of the interaction. Just download the feature geometries to the client using GeoJSON, KML, or some other vector format, and use SVG or canvas to render the geometries.</p>
<p>But if you try to <a href="http://www.guardian.co.uk/world/datablog/interactive/2010/oct/23/wikileaks-iraq-deaths-map" target="_blank">map all deaths in the Iraq war</a>, <a href="http://afghanistanelectiondata.org/election/2009/data/#zoom=2&amp;lat=34.69413&amp;lon=68.00031&amp;layers=afghanistan-ethnic&amp;baseLayers=afghanistan-grey" target="_blank">show election data in a choropleth map</a> or <a href="http://map.geoportail.lu/?lang=en&amp;zoom=8&amp;X=74606&amp;Y=76821&amp;layers=buildings&amp;layers_indices=3&amp;layers_opacity=1&amp;layers_visibility=true&amp;bgLayer=voidLayer&amp;selectedNode=node_addresses1" target="_blank">display a large number of buildings</a>, then rendering your features inside the browser does not work that well any more. For several reasons: First, it will take some time to transfer the whole vector data to the client. Then, rendering gets slow and your map does not feel that responsive any more when panning or zooming.</p>
<p>So at this point you will do the same as you (or someone else) did with your base map: You will render your geometries on the server-side and serve the data as image tiles. But with plain images we are loosing interactivity! We still want to be able to click on features and we want visual feedback when hovering a feature, so that we know where to click! So, that is what this post is about: <strong>How do you preserve interactivity when using feature tiles?</strong></p>
<p><strong>In the following we will take a look at three different web mapping applications that use tiles for displaying features and we will compare the different approaches taken to make these tile layers interactive.<span id="more-125"></span></strong></p>
<h3>Google Fusion Tables</h3>
<p><a href="http://www.google.com/fusiontables" target="_blank">Google Fusion Tables</a> is a service that lets you upload large sets of tabular data. The data can then be visualized using different kinds of charts, but you can also show your data on a map.</p>
<p>For example, this is a <a href="http://www.google.com/fusiontables/DataSource?dsrcid=210217" target="_blank">table with all counties of the USA</a>. To get a map with all counties, you just have to hit <em>Visualize » Map</em>. The counties are rendered as red dots that you can click on. If you zoom in a bit further, the counties will be shown as polygons.</p>
<p style="text-align:center;"><a href="http://whatwasitagain.files.wordpress.com/2011/06/fusion-tables-usa-counties1.png"><img class="size-medium wp-image-146" style="margin-left:5px;margin-right:5px;" title="Google Fusion Tables: United States Counties" src="http://whatwasitagain.files.wordpress.com/2011/06/fusion-tables-usa-counties1.png?w=300&#038;h=236" alt="" width="300" height="236" /></a></p>
<h4 style="text-align:left;">Image tiles</h4>
<p style="text-align:left;">Now let&#8217;s try to understand how it works! The features are rendered on transparent tiles that are fetched <a href="http://code.google.com/intl/en/apis/maps/documentation/javascript/maptypes.html#TileCoordinates" target="_blank">just like the tiles of the base map</a>. For example this is the <a href="http://mt0.google.com/mapslt?lyrs=ft:210217|s:select%20col4%20from%20210217%20|h:false|uit:AIGcsfM_tVdc0DJ2ucYf0FrsPlxv22KwIA|t:1307554407&amp;x=3&amp;y=5&amp;z=4&amp;w=256&amp;h=256&amp;source=maps_api&amp;hl=de" target="_blank">URL for tile (3, 5) at zoom-level 4</a>:</p>
<p><pre class="brush: xml;">http://mt0.google.com/mapslt?
  lyrs=ft:210217
   |s:select col4 from 210217
   |h:false|uit:AIGcsfM_tVdc0DJ2ucYf0FrsPlxv22KwIA
   |t:1307554407
  &amp;x=3&amp;y=5&amp;z=4
  &amp;w=256&amp;h=256
  &amp;source=maps_api
</pre></p>
<p>Line 2 (<em>lyrs=ft:210217</em>) contains the ID of the table, the query that selects the geometries is in line 3 (<em>select col4 from 210217</em>). The information about which tile is requested is in line 6 (<em>x=3&amp;y=5&amp;z=4</em>).</p>
<h4>Interactive markers</h4>
<p>So much about the tile images. But how does the browser know on which areas of the images you can click on? At the beginning, when the map is displayed for the first time, the Google Map client library just fetches the tile images. But once you start hovering the map with your mouse pointer, the client will dynamically request position data for the tile that you are just hovering. For example a request can look like this:</p>
<p><pre class="brush: xml;">http://mt0.google.com/vt/ft
  ?lyrs=ft:210217
   |s:select col4 from 210217
   |h:false|uit:AIGcsfNfL6pLSANzTVnbSlwncVdo-FccYA
   |t:1307632793
  &amp;las=tuvt
  &amp;z=3
  &amp;source=maps_api
  &amp;callback=_xdc_._bgopuz14u
</pre></p>
<p>The request looks similar to the tile URL, but the tile coordinates (for example: <em>x=3&amp;y=5)</em> are not passed in clear text. I guess the coordinates are either encoded in line 6 (<em>las=tuvt</em>) or in line 9 (<em>callback=_xdc_._bgopuz14u</em>). The response for this request was:</p>
<p><pre class="brush: xml;">_xdc_._bgopuz14u &amp;&amp; _xdc_._bgopuz14u([
 {
  id:&quot;tuvt&quot;,
  base:[295698432,668991488],
  zrange:[3,3],
  layer:&quot;ft:210217
    |h:false
    |s:select col4 from 210217
    |t:1307632793
    |uit:AIGcsfNfL6pLSANzTVnbSlwncVdo-FccYA&quot;,
  features:[
   {
    id:&quot;4:6113019567&quot;,
    a:[0,0],
    bb:[-4,-4,4,4]
   },
   {
     id:&quot;4:6113167168&quot;,
     a:[-25165824,-2097152],
     bb:[-4,-4,4,4]
   },
   ...
  ]
}])
</pre></p>
<p>If the tile contains features, they are listed in the <em>features</em> attribute (line 11). Every feature has an identifier (<em>id:&#8221;4:6113019567&#8243;</em>), a position (<em>a:[0,0]</em>) and a bounding box in pixels relative to the position (<em>bb:[-4,-4,4,4]</em>) that marks the area you can click on. The feature position is probably relative to the tile position (line 4: <em>base:[295698432,668991488]</em>). And I am not really sure what unit Google is using for the coordinates, pixel coordinates or some <em>real world</em> coordinate system?</p>
<h4>Interactive polygons</h4>
<p>So the clickable area for points features is a rectangle, which works fine for small symbols. But for polygons and lines a rectangle would be too imprecise. That is why the response for a tile containing polygons or lines looks <em>a bit</em> different:</p>
<p><pre class="brush: xml;">_xdc_._1kgooi20ar &amp;&amp; _xdc_._1kgooi20ar([{
  id:&quot;tuvuuv&quot;,
  zrange:[5,5],
  layer:&quot;ft:210217
   |h:false
   |s:select col4 from 210217
   |t:1307550131|uit:AIGcsfOMgmq2ezQxiAgCamH-DAbYFlDFfA&quot;,
  features:
   [
    {id:&quot;4:6112682473&quot;},
    {id:&quot;4:6112987488&quot;},
    ...
   ],
  raster:&quot;?A?A??ED?ED?ED?ED? ... D@B@wD@AEGD?D@&quot;
}])
</pre></p>
<p>You still have the feature list, but now only the feature identifiers are given. Instead of feature positions you have this weird looking string in line 14 (<em>raster:&#8221;..&#8221;</em>). This string contains information about which feature was rendered to which pixel. At first, this sounds like a lot of data, but there are not many responses larger than 10 KB (gzipped). Unfortunately there is no information available about how this works in detail, but our next application uses a very  similar approach.</p>
<h3>Mapbox: TileMill</h3>
<p>Our next example is the tile server <a href="http://mapbox.com/#/tilemill" target="_blank">TileMill</a> based on <a href="http://nodejs.org/" target="_blank">node.js</a> and developed by <a href="http://developmentseed.org/" target="_blank">DevelopmentSeed</a>. First, let&#8217;s take a look at this <a href="http://mapbox.com/#/tileset/geography-class" target="_blank">beautiful map</a> made with TileMill using OpenLayers as mapping client:</p>
<p style="text-align:center;"><a href="http://whatwasitagain.files.wordpress.com/2011/06/mapbox-sample.png"><img class="aligncenter size-medium wp-image-168" style="margin-top:5px;margin-bottom:5px;" title="MapBox: Geography Class" src="http://whatwasitagain.files.wordpress.com/2011/06/mapbox-sample.png?w=300&#038;h=181" alt="" width="300" height="181" /></a></p>
<p style="text-align:left;">Like Google Fusion Tables, TileMill uses two different files for feature tiles: the tile image and a JSON file containing information that makes the image interactive. The JSON file is also loaded on-the-fly when you hover a tile. But unlike Google Fusion Tables, TileMill is an open-source project (GitHub: <a href="https://github.com/mapbox/tilemill" target="_blank">mapbox/tilemill</a>), so that we can actually see how it works.</p>
<h4 style="text-align:left;">UTFGrid</h4>
<p style="text-align:left;">For TileMill the format of these JSON files is specified in the MBTiles specification (<a href="https://github.com/mapbox/mbtiles-spec/blob/master/1.1/utfgrid.md" target="_blank">MBTiles: UTFGrid</a>). For example this is the <a href="http://c.tiles.mapbox.com/mapbox/1.0.0/geography-class/4/7/10.grid.json?callback=grid&amp;_1307715136267=" target="_blank">JSON file</a> for <a href="http://c.tiles.mapbox.com/mapbox/1.0.0/geography-class/4/7/10.png" target="_blank">tile (7,10) at zoom level 4</a> (the strings in line 3, 5 and 6 were shortened):</p>
<p><pre class="brush: xml;">grid({
  &quot;grid&quot;:[
    &quot;                !!!!!!!!!!!!!!!    &quot;,
    ...
    &quot;         )))))))))(((((((((((((((((&quot;,
    &quot;          )))))))((((((((((((((((((&quot;],
  &quot;keys&quot;:[
    &quot;&quot;,
    &quot;GBR&quot;,
    &quot;IRL&quot;,
    &quot;IMN&quot;,
    &quot;FRA&quot;,
    &quot;GGY&quot;,
    &quot;JEY&quot;,
    &quot;ESP&quot;,
    &quot;PRT&quot;],
  &quot;data&quot;:{
    &quot;ESP&quot;:{&quot;ABBREV&quot;:&quot;Sp.&quot;, ...},
    &quot;FRA&quot;:{&quot;ABBREV&quot;:&quot;Fr.&quot;, ...},
    ...}
});
</pre></p>
<p style="text-align:left;">The JSON string contains three main attributes: <em>grid</em> (line 2), <em>keys</em> (line 7) and <em>data</em> (line 17). The attribute <em>keys</em> contains a list of all feature identifiers and the optional attribute <em>data</em> can be used to provide additional information for a feature (for example the country name).</p>
<p style="text-align:left;">The attribute <em>grid</em> is a bit more interesting. It is an array of 64 strings where as each string contains 64 characters. So we have got an 64&#215;64 grid of characters. If we map this grid to our 256&#215;256 pixel tile, we see that each character stores the data for 4&#215;4 pixels. So a character contains the encoded feature identifier, if a feature was rendered to the corresponding 4&#215;4 pixel area.</p>
<p style="text-align:left;">The following graphic shows the original tile and a screen-shot of the grid array displayed in a text editor and resized to match the 256&#215;256 pixel tile. As you can see, the shapes look very similar.</p>
<p style="text-align:center;"><a href="http://whatwasitagain.files.wordpress.com/2011/06/utf-tile.png"><img class="aligncenter size-full wp-image-174" style="margin-top:5px;margin-bottom:5px;" title="Real tile - UTFGrid" src="http://whatwasitagain.files.wordpress.com/2011/06/utf-tile.png?w=480&#038;h=240" alt="" width="480" height="240" /></a></p>
<p style="text-align:left;">A cell of the grid does not directly contain one of the identifiers given in the <em>keys</em> list. To keep the amount of data low, the identifier is encoded. For example, let&#8217;s assume the user clicks on Spain, somewhere in the lower right corner of the tile. To get the feature identifier we have to do the following:</p>
<ul>
<li>We do a lookup in the grid using the pixel coordinates and get the character &#8220;(&#8221; (for example in line 6).</li>
<li>Now we take a look at the <a href="http://en.wikipedia.org/wiki/UTF-8#Codepage_layout" target="_blank">UTF table</a> and see that the character &#8220;(&#8221; equals the <a href="http://en.wikipedia.org/wiki/Code_point" target="_blank">codepoint</a> value 40.</li>
<li>According to the specification (<a href="https://github.com/mapbox/mbtiles-spec/blob/master/1.1/utfgrid.md" target="_blank">UTFGrid: Encoding IDs</a>) we have to subtract 32 and 1 (because 40 &gt;= 35), so we get: 40 &#8211; 32 &#8211; 1 = 7</li>
<li>The number 7 is the index of the feature identifier in the <em>keys</em> array. <em>key[7]</em> is &#8220;ESP&#8221; (line 15), so we have found Spain which is correct.</li>
</ul>
<p>DevelopmentSeed luckily provides extensions for the mapping clients <a href="http://openlayers.org/" target="_blank">OpenLayers</a>, <a href="https://github.com/stamen/modestmaps-js" target="_blank">Modest Maps</a>, <a href="http://leaflet.cloudmade.com/" target="_blank">Leaflet</a> and the <a href="http://code.google.com/intl/en/apis/maps/documentation/javascript/" target="_blank">Google Maps API</a>, so that you do not have to care about the encoding and loading the JSON files. The library containing these extensions is called <a href="https://github.com/mapbox/wax" target="_blank">Wax</a> (the file <a href="https://github.com/mapbox/wax/blob/master/control/lib/gridutil.js" target="_blank">gridutil.js</a> reads the grid).</p>
<p>To generate the JSON files, TileMill uses the Mapnik <a href="http://trac.mapnik.org/wiki/MapnikRenderers#grid_renderer" target="_blank">grid_renderer</a> (via <a href="https://github.com/mapnik/node-mapnik" target="_blank">node-mapnik</a>: the file <a href="https://github.com/mapnik/node-mapnik/blob/master/src/js_grid_utils.hpp" target="_blank">js_grid_utils.grid2utf</a> writes the grid). The tiles can be served using <a href="https://github.com/mapbox/tilestream" target="_blank">TileStream</a>. More implementations of the MBTiles specification can be found <a href="https://github.com/mapbox/mbtiles-spec/wiki/Implementations" target="_blank">here</a>.</p>
<p><strong>Update:</strong> <a href="http://developmentseed.org/blog/2011/apr/21/presenting-map-interactivity-without-flash-where-20/" target="_blank">Presenting on Map Interactivity Without Flash at Where 2.0</a> and <a href="http://developmentseed.org/blog/2011/09/21/how-interactivity-works-utfgrid/" target="_blank">How Interactivity Works with UTFGrid</a> give a good explanation about UTFGrid.</p>
<h3>Switzerland Mobility</h3>
<p>Our last example is the map on <a href="http://map.veloland.ch/?lang=en" target="_blank">Switzerland Mobile</a>, which was developed by <a href="http://www.camptocamp.com/" target="_blank">Camptocamp</a> using <a href="http://www.mapfish.org/" target="_blank">MapFish</a> and <a href="http://openlayers.org/" target="_blank">OpenLayers</a>.</p>
<p style="text-align:center;"><a href="http://whatwasitagain.files.wordpress.com/2011/06/veloland.png"><img class="aligncenter size-medium wp-image-178" style="margin-top:5px;margin-bottom:5px;" title="Veloland Schweiz" src="http://whatwasitagain.files.wordpress.com/2011/06/veloland.png?w=300&#038;h=181" alt="" width="300" height="181" /></a></p>
<p style="text-align:left;">The map consists of ~50 POI and line layers that can be switched on and off arbitrarily. The different layers are rendered on the same tile so that the browser does not have to deal with keeping all tiles of all layers properly lined up when panning.</p>
<p style="text-align:left;">The layers are interactive: Your mouse cursor turns into a pointer when you hover a track or POI and you can click on these features.</p>
<p style="text-align:left;">How does it work? There is no additional JSON file for every tile like in the first two examples. A different approach is taken: When you hover the map, the client constantly keeps asking the server if there are any features nearby the position your mouse cursor is pointing to. If a new request is made before a response was received for an old request, the old request is aborted, as you can see in the following screen-shot:</p>
<p style="text-align:left;"><a href="http://whatwasitagain.files.wordpress.com/2011/06/veloland-firebugs.png"><img class="aligncenter size-medium wp-image-180" style="margin-top:5px;margin-bottom:5px;" title="Switzerland Mobility: Requests" src="http://whatwasitagain.files.wordpress.com/2011/06/veloland-firebugs.png?w=300&#038;h=100" alt="" width="300" height="100" /></a>If there are features within a certain distance to the mouse position, the server just returns &#8220;<em>got something here</em>&#8220;. This tells the client to change the cursor style to a pointer. If you click on the map, a new request is made which directly returns the HTML code to be displayed in a map pop-up.</p>
<p style="text-align:left;"><a href="http://whatwasitagain.files.wordpress.com/2011/06/veloland-multiple-hits.png"><img class="aligncenter size-medium wp-image-184" style="margin-top:5px;margin-bottom:5px;" title="Switzerland Mobility: Multiple Hits" src="http://whatwasitagain.files.wordpress.com/2011/06/veloland-multiple-hits.png?w=300&#038;h=241" alt="" width="300" height="241" /></a>Often there is not only one biking or hiking track at the mouse position, so all hits are displayed in the pop-up (as shown in the above screen-shot). With the current <a href="https://github.com/mapbox/mbtiles-spec/blob/master/1.1/utfgrid.md" target="_blank">UTFGrid specification</a> you could only get one hit, because it only allows to store one feature identifier per grid cell. But the two different approaches could be combined: You could use the grid to decide whether your mouse cursor is hovering a feature, and then, when clicking somewhere, you would make a new request. This would reduce the number of server requests and you still would get all hits.</p>
<h3 style="text-align:left;">Wrap-up</h3>
<p>The <a href="https://github.com/mapbox/mbtiles-spec/blob/master/1.1/utfgrid.md" target="_blank">UTFGrid specification</a> is a promising technique to make feature tile layers interactive. The size of the JSON file containing the grid is reasonable through <a href="http://en.wikipedia.org/wiki/Run-length_encoding" target="_blank">run-length encoding</a> and and <a href="http://en.wikipedia.org/wiki/Gzip" target="_blank">gzipping</a>. Additionally <a href="https://github.com/mapbox/wax" target="_blank">Wax</a> makes sure that only those grids are requested that are actually needed.</p>
<p>Wouldn&#8217;t this make a good <em>Web Map Feature Tile Service</em> specification (<em>WMFTS</em>), combining <a href="http://www.opengeospatial.org/standards/wfs" target="_blank">WFS</a> and <a href="http://www.opengeospatial.org/standards/wmts" target="_blank">WMTS</a>?</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/whatwasitagain.wordpress.com/125/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/whatwasitagain.wordpress.com/125/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/whatwasitagain.wordpress.com/125/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/whatwasitagain.wordpress.com/125/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/whatwasitagain.wordpress.com/125/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/whatwasitagain.wordpress.com/125/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/whatwasitagain.wordpress.com/125/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/whatwasitagain.wordpress.com/125/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/whatwasitagain.wordpress.com/125/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/whatwasitagain.wordpress.com/125/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/whatwasitagain.wordpress.com/125/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/whatwasitagain.wordpress.com/125/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/whatwasitagain.wordpress.com/125/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/whatwasitagain.wordpress.com/125/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=whatwasitagain.wordpress.com&amp;blog=4842555&amp;post=125&amp;subd=whatwasitagain&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://whatwasitagain.wordpress.com/2011/06/12/interactive-feature-tile-layers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a0121f9cc309e7dff279723b71e2ba85?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">whatwasitagain</media:title>
		</media:content>

		<media:content url="http://whatwasitagain.files.wordpress.com/2011/06/fusion-tables-usa-counties1.png?w=300" medium="image">
			<media:title type="html">Google Fusion Tables: United States Counties</media:title>
		</media:content>

		<media:content url="http://whatwasitagain.files.wordpress.com/2011/06/mapbox-sample.png?w=300" medium="image">
			<media:title type="html">MapBox: Geography Class</media:title>
		</media:content>

		<media:content url="http://whatwasitagain.files.wordpress.com/2011/06/utf-tile.png" medium="image">
			<media:title type="html">Real tile - UTFGrid</media:title>
		</media:content>

		<media:content url="http://whatwasitagain.files.wordpress.com/2011/06/veloland.png?w=300" medium="image">
			<media:title type="html">Veloland Schweiz</media:title>
		</media:content>

		<media:content url="http://whatwasitagain.files.wordpress.com/2011/06/veloland-firebugs.png?w=300" medium="image">
			<media:title type="html">Switzerland Mobility: Requests</media:title>
		</media:content>

		<media:content url="http://whatwasitagain.files.wordpress.com/2011/06/veloland-multiple-hits.png?w=300" medium="image">
			<media:title type="html">Switzerland Mobility: Multiple Hits</media:title>
		</media:content>
	</item>
		<item>
		<title>Geo BI with Google Fusion Tables?</title>
		<link>http://whatwasitagain.wordpress.com/2011/06/03/geo-bi-google-fusion-tables/</link>
		<comments>http://whatwasitagain.wordpress.com/2011/06/03/geo-bi-google-fusion-tables/#comments</comments>
		<pubDate>Fri, 03 Jun 2011 18:46:15 +0000</pubDate>
		<dc:creator>whatwasitagain</dc:creator>
				<category><![CDATA[Geo]]></category>
		<category><![CDATA[geo bi]]></category>
		<category><![CDATA[google fusion tables]]></category>
		<category><![CDATA[google maps]]></category>

		<guid isPermaLink="false">http://whatwasitagain.wordpress.com/?p=81</guid>
		<description><![CDATA[Google Fusion Tables has been around for a while, but inspired by the talks at Google I/O 2011 I felt like finally giving it a try. For quite a while I wanted to generate some maps for my family&#8217;s winery, so I thought, let&#8217;s see how this would work with Google Fusion Tables. A map [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=whatwasitagain.wordpress.com&amp;blog=4842555&amp;post=81&amp;subd=whatwasitagain&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.google.com/fusiontables" target="_blank">Google Fusion Tables</a> has been around for a while, but inspired by the talks at <a href="http://www.google.com/events/io/2011/sessions/managing-and-visualizing-your-geospatial-data-with-fusion-tables.html" target="_blank">Google I/O 2011</a> I felt like finally giving it a try. For quite a while I wanted to generate some maps for my family&#8217;s <a title="Weingut Sonenbuerg - Erwin Sauerwein" href="http://www.erwin-sauerwein.de/" target="_blank">winery</a>, so I thought, let&#8217;s see how this would work with Google Fusion Tables.<span id="more-81"></span></p>
<h2>A map with all customers</h2>
<p>I wanted to start simple, so my first goal was to get a map showing a dot for every customer. The first thing to do is getting your data into Google Fusion Tables, so you have to prepare your data for the import.</p>
<h4>Geocoding your addresses with Google Fusion Tables</h4>
<p>To display a customer on a map, all customer addresses have to be geocoded. Google Fusion Table takes care of the <a title="What is geocoding? How do I geocode my data?" href="http://www.google.com/support/fusiontables/bin/answer.py?hl=en&amp;answer=1012281" target="_blank">geocoding</a>, you just have to make sure that the address is stored in a single column and not in multiple columns. For example the following SQL query generates a valid import table:</p>
<p><pre class="brush: sql;">
select customerId, name1, name2, ...,
(street &amp; ', ' &amp; zipCode &amp; ' ' &amp; city &amp; ', ' &amp; country) as address
from customers
</pre></p>
<p>The result table of this query can directly be imported in Google Fusion Tables, and then simply be geocoded using the column &#8220;address&#8221; (<em>File » Geocode</em>).</p>
<h4>&#8220;Manually&#8221; geocoding</h4>
<p>Unfortunately, you can only geocode <a href="http://code.google.com/intl/en/apis/maps/documentation/geocoding/#Limits" target="_blank">2500 addresses per day</a>, so I couldn&#8217;t use the built-in geocoder for my customer table. I had to take a different approach: The <a href="http://www.mapbender.org" target="_blank">Mapbender</a> project provides a file with the polygons of all German postal codes (<a href="http://sourceforge.net/projects/mapbender/files/Data/PLZ/" target="_blank">plz.zip</a>). I took this file, imported the data into a PostGIS database and then generated a KML file with the centroids of all postal codes. Then I imported the KML file into Google Fusion Tables and already could display the postal codes on a map.<a href="http://whatwasitagain.files.wordpress.com/2011/06/postal-codes.png"><img class="aligncenter size-medium wp-image-94" title="All postal codes on a map" src="http://whatwasitagain.files.wordpress.com/2011/06/postal-codes.png?w=300&#038;h=218" alt="" width="300" height="218" /></a>So now I had my customer table (with columns like <em>customerId</em>, <em>name</em> and <em>zipCode</em>) and the postal code table (with column <em>zipCode</em> and <em>geometry</em>). In a relational database you would perform a <em>join</em> to connect the two tables using the <em>zipCode</em> column. In Google Fusion Tables this join is called <a href="http://www.google.com/support/fusiontables/bin/answer.py?hl=en&amp;answer=171254" target="_blank">Merge</a> (actually merge is a <a href="http://en.wikipedia.org/wiki/Left_outer_join#Outer_joins" target="_blank">left-outer join</a>). When you merge two tables, the data of the two tables is not copied into the new table. A merged table is more like a <a href="http://en.wikipedia.org/wiki/View_%28database%29" target="_blank">view</a>. So when you make changes in the original tables, these changes are also visible in the merged table.</p>
<h4>Aggregate your data</h4>
<p>Ok, now I could display the customers on a map using the merged table. But there was a big drawback: No matter if there was only one customer or 20 customers in a postal code area, on the map you would only see a single point for that postal code. So I generated a new table thats consists of two columns: the postal code and the number of customers within the postal code area.</p>
<p><pre class="brush: sql;">
select zipCode, count(*) as customerCount
from customers
group by zipCode
</pre></p>
<p>But I also wanted to take it a step further and group all customers together whose postal code number is the same in the first three digits (the call of function mid returns the first three digits):</p>
<p><pre class="brush: sql;">
select zipCodeGrouped, sum(customerCount) as sumCustomerCount
from (
   select (Mid(zipCode, 1, 3) || '00') as zipCodeGrouped, count(*) as customerCount
   from customers
   group by zipCode)
group by zipCodeGrouped
</pre></p>
<p>Imported in Google Fusion Tables, the table looked like this:</p>
<p style="text-align:left;"><a href="http://whatwasitagain.files.wordpress.com/2011/06/postal-code-grouped.png"><img class="aligncenter size-full wp-image-105" style="margin-top:5px;margin-bottom:5px;" title="Customers grouped" src="http://whatwasitagain.files.wordpress.com/2011/06/postal-code-grouped.png?w=480" alt=""   /></a>For the new postal code groups I had to create a new KML file in which the geometries of postal codes, that have the same first three digits, were merged using the PostGIS function <a href="http://postgis.refractions.net/docs/ST_Union.html" target="_blank">ST_Union</a>.</p>
<h4 style="text-align:left;">Configure the map styling</h4>
<p style="text-align:left;">Once your table has a geometry column, you can put your geometries on a map simply by clicking on <em>Visualize » Map</em>. But often you also want to visualize data associated with the geometries, in my example the number of customers in a postal code group. So I changed the style of postal code polygons to use a gradient.</p>
<p style="text-align:left;">Postal code areas with many customers are using a darker color, while areas with only a few customer use a lighter color. And this is what the final map looked like:</p>
<p style="text-align:center;"><a href="http://whatwasitagain.files.wordpress.com/2011/06/postal-code-grouped-map1.png"><img class="aligncenter size-medium wp-image-110" title="Customer distribution" src="http://whatwasitagain.files.wordpress.com/2011/06/postal-code-grouped-map1.png?w=300&#038;h=204" alt="" width="300" height="204" /></a></p>
<h3 style="text-align:left;">What is cool</h3>
<ul>
<li><strong>Easy to get started</strong><br />
Even if you have never heard of GIS, you can easily import your data, geocode your addresses and create a map.</li>
<li><strong>Just scales</strong><br />
This is what I really like about Google Fusion Tables! No matter if you have 10 points or 100 000 points, 10 simple polygons or 100 000 very complex polygons &#8211; <a title="Google Fusion Tables Performance" href="http://google-io-preso.googlecode.com/svn/trunk/slides.html#36" target="_blank">you won&#8217;t notice a difference</a>. Instead of rendering the geometries on the client side, the geometries are rendered on image tiles in the Google cloud. So you also don&#8217;t have to worry about simplifying your geometries, Google Fusion Tables does that job for you.</li>
<li><strong>Integrates with the Google Maps API</strong><br />
Google added a <a href="http://code.google.com/intl/en/apis/maps/documentation/javascript/overlays.html#FusionTables" target="_blank">Fusion Table Layer</a> to their Google Maps API, so it got a lot easier to publish your data on your own maps.</li>
</ul>
<h3 style="text-align:left;">What is not so cool (yet?)</h3>
<ul>
<li><strong>Limited styling</strong><br />
Especially for points the styling options are limited. For points, you can currently only choose a marker out of a limited set of markers. Proportional symbols, chart symbols and labels would be nice. Google Fusion Tables is still beta, so likely there will be improvements.</li>
<li><strong>Style of background maps</strong><br />
The standard background maps provide too much additional information, that you are not interested in. For the above example you don&#8217;t need the street network, a few larger cities would be enough for the background map. If you are using your layer with the Google Maps API, you can <a title="Styled Maps" href="http://code.google.com/intl/en/apis/maps/documentation/javascript/maptypes.html#StyledMaps" target="_blank">change the map style</a>. But not directly in Google Fusion Tables.</li>
<li><strong>No spatial joins/filters/operations<br />
</strong>Queries like &#8220;Get me all customers in this area that live not more than 10 km away from the next store.&#8221; are not possible in Google Fusion Tables (<a href="http://mano-demos.googlecode.com/svn/trunk/slides/georoadshow/hamburg/hamburgjsmeetup.html#10" target="_blank">without using the API</a>).</li>
</ul>
<p>So would I use Google Fusion Table to generate business reports? Preparing the postal code geometries was a bit tedious, but you only have to do it once. Then you could import your data using the <a href="http://code.google.com/intl/de/apis/fusiontables/" target="_blank">Google Fusion Tables API</a>. In my case I would prefer a solution that integrates with our existing <a href="http://community.pentaho.com/projects/bi_platform/" target="_blank">Pentaho BI Platform</a> setup.</p>
<h4>Links</h4>
<ul>
<li><a href="http://www.google.com/fusiontables" target="_blank">Google Fusion Table</a></li>
<li><a href="http://www.google.com/events/io/2011/sessions/managing-and-visualizing-your-geospatial-data-with-fusion-tables.html" target="_blank">&#8220;Managing and visualizing your geospatial data with Fusion Tables&#8221;</a> at Google I/O 2011 (<a href="http://google-io-preso.googlecode.com/svn/trunk/slides.html#1" target="_blank">Slides</a>)</li>
<li><a href="http://code.google.com/intl/de/apis/fusiontables/" target="_blank">Google Fusion Tables API</a></li>
<li>Google Maps API: <a href="http://code.google.com/intl/en/apis/maps/documentation/javascript/overlays.html#FusionTables" target="_blank">Fusion Table Layer</a></li>
<li><a href="http://mano-demos.googlecode.com/svn/trunk/slides/georoadshow/hamburg/hamburgjsmeetup.html#1" target="_blank">&#8220;New Features in Google Geo Fusion Tables, Places API and Custom Street View&#8221;</a> at Hamburg JS Meetup 2011</li>
</ul>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/whatwasitagain.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/whatwasitagain.wordpress.com/81/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/whatwasitagain.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/whatwasitagain.wordpress.com/81/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/whatwasitagain.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/whatwasitagain.wordpress.com/81/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/whatwasitagain.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/whatwasitagain.wordpress.com/81/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/whatwasitagain.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/whatwasitagain.wordpress.com/81/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/whatwasitagain.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/whatwasitagain.wordpress.com/81/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/whatwasitagain.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/whatwasitagain.wordpress.com/81/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=whatwasitagain.wordpress.com&amp;blog=4842555&amp;post=81&amp;subd=whatwasitagain&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://whatwasitagain.wordpress.com/2011/06/03/geo-bi-google-fusion-tables/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a0121f9cc309e7dff279723b71e2ba85?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">whatwasitagain</media:title>
		</media:content>

		<media:content url="http://whatwasitagain.files.wordpress.com/2011/06/postal-codes.png?w=300" medium="image">
			<media:title type="html">All postal codes on a map</media:title>
		</media:content>

		<media:content url="http://whatwasitagain.files.wordpress.com/2011/06/postal-code-grouped.png" medium="image">
			<media:title type="html">Customers grouped</media:title>
		</media:content>

		<media:content url="http://whatwasitagain.files.wordpress.com/2011/06/postal-code-grouped-map1.png?w=300" medium="image">
			<media:title type="html">Customer distribution</media:title>
		</media:content>
	</item>
		<item>
		<title>Moving your SVN repository from Kenai to Google Code with svnsync</title>
		<link>http://whatwasitagain.wordpress.com/2010/02/15/moving-your-svn-repository-from-kenai-to-google-code-with-svnsync/</link>
		<comments>http://whatwasitagain.wordpress.com/2010/02/15/moving-your-svn-repository-from-kenai-to-google-code-with-svnsync/#comments</comments>
		<pubDate>Sun, 14 Feb 2010 22:10:10 +0000</pubDate>
		<dc:creator>whatwasitagain</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[google-code]]></category>
		<category><![CDATA[kenai]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[svnsync]]></category>

		<guid isPermaLink="false">http://whatwasitagain.wordpress.com/?p=68</guid>
		<description><![CDATA[Do you want to move your svn repository but without losing your history? No problem with svnsync! Create a new Google Code project with a SVN repository. Reset the Google Code SVN repository. By default every Google Code SVN repository does have an initial structure, but svnsync needs an empty repository. So go to the [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=whatwasitagain.wordpress.com&amp;blog=4842555&amp;post=68&amp;subd=whatwasitagain&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Do you want to move your svn repository but without losing your history? No problem with <a href="http://svnbook.red-bean.com/en/1.4/svn.ref.svnsync.html" target="_blank">svnsync</a>!</p>
<ol>
<li>Create a new Google Code project with a SVN repository.</li>
<li>Reset the Google Code SVN repository.<br />
By default every Google Code SVN repository does have an initial structure, but svnsync needs an empty repository. So go to the &#8220;Source&#8221; tab and at the bottom of the page there is a link &#8220;reset this repository&#8221;.</li>
<li>Now open up a terminal.<br />
<pre class="brush: ruby;">$ export FROMREPO=https://svn.kenai.com/svn/YOUR-PROJECT
$ export TOREPO=https://YOUR-PROJECT.googlecode.com/svn/</pre></li>
<li>Then you will be asked for your username/password after running this command.<br />
<pre class="brush: ruby;">$ svnsync init ${TOREPO} ${FROMREPO}</pre></li>
<li>And finally to start the process, execute the following:<br />
<pre class="brush: ruby;">$ svnsync --non-interactive sync ${TOREPO}</pre></li>
</ol>
<p>See also: <a title="using-svnsync" href="http://journal.paul.querna.org/articles/2006/09/14/using-svnsync/" target="_blank">using-svnsync</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/whatwasitagain.wordpress.com/68/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/whatwasitagain.wordpress.com/68/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/whatwasitagain.wordpress.com/68/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/whatwasitagain.wordpress.com/68/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/whatwasitagain.wordpress.com/68/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/whatwasitagain.wordpress.com/68/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/whatwasitagain.wordpress.com/68/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/whatwasitagain.wordpress.com/68/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/whatwasitagain.wordpress.com/68/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/whatwasitagain.wordpress.com/68/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/whatwasitagain.wordpress.com/68/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/whatwasitagain.wordpress.com/68/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/whatwasitagain.wordpress.com/68/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/whatwasitagain.wordpress.com/68/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=whatwasitagain.wordpress.com&amp;blog=4842555&amp;post=68&amp;subd=whatwasitagain&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://whatwasitagain.wordpress.com/2010/02/15/moving-your-svn-repository-from-kenai-to-google-code-with-svnsync/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a0121f9cc309e7dff279723b71e2ba85?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">whatwasitagain</media:title>
		</media:content>
	</item>
		<item>
		<title>Codemetriken in PHP</title>
		<link>http://whatwasitagain.wordpress.com/2009/05/19/codemetriken-in-php/</link>
		<comments>http://whatwasitagain.wordpress.com/2009/05/19/codemetriken-in-php/#comments</comments>
		<pubDate>Tue, 19 May 2009 08:07:08 +0000</pubDate>
		<dc:creator>whatwasitagain</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[code-metrics]]></category>
		<category><![CDATA[code-quality]]></category>
		<category><![CDATA[qa]]></category>

		<guid isPermaLink="false">http://whatwasitagain.wordpress.com/?p=42</guid>
		<description><![CDATA[Eine Übersicht von Tools, die zur Verbesserung der Codequalität in PHP eingesetzt werden können: phpcpd (PHP Copy&#38;Paste Detection) phploc (PHP Lines of Code) PHP Depend PHPCode Sniffer PHPUnit &#8211; CodeCoverage phpcpd (PHP Copy&#38;Paste Detection) Einzige Aufgabe dieses Tools von Sebastian Bergmann ist es, den Code auf die Verwendung des Copy&#38;Paste-Anti-Pattern hin zu untersuchen. Ab wann [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=whatwasitagain.wordpress.com&amp;blog=4842555&amp;post=42&amp;subd=whatwasitagain&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Eine Übersicht von Tools, die zur Verbesserung der Codequalität in PHP eingesetzt werden können:</p>
<ul>
<li><a title="phpcpd" href="#phpcpd">phpcpd (PHP Copy&amp;Paste Detection)</a></li>
<li><a title="phploc" href="#phploc">phploc (PHP Lines of Code)</a></li>
<li><a title="PHP Depend" href="#phpdepend">PHP Depend</a></li>
<li><a title="PHP CodeSniffer" href="#phpcs">PHPCode Sniffer</a></li>
<li><a title="PHPUnit - CodeCoverage" href="#phpunitcc">PHPUnit &#8211; CodeCoverage</a></li>
</ul>
<p><a name="phpcpd"></a></p>
<h2>phpcpd (PHP Copy&amp;Paste Detection)</h2>
<p><!-- 		@page { margin: 2cm } 		P.sdfootnote { margin-left: 0.5cm; text-indent: -0.5cm; margin-bottom: 0cm; font-size: 10pt } 		P { margin-bottom: 0.21cm } 		A:link { so-language: zxx } 		A.sdfootnoteanc { font-size: 57% } -->Einzige Aufgabe dieses Tools von <a href="http://sebastian-bergmann.de/" target="_blank">Sebastian Bergmann</a> ist es, den Code auf die Verwendung des <a title="Copy&amp;Paste-Programmierung" href="http://en.wikipedia.org/wiki/Copy_and_paste_programming" target="_blank">Copy&amp;Paste-Anti-Pattern</a> hin zu untersuchen. Ab wann eine Code-Passage als „kopiert“ gilt, lässt sich über die Anzahl der Zeichen/Zeilen, die identisch sind, einstellen.</p>
<p>Eine Beispiel-Ausgabe findet sich auf der <a title="phpcpd" href="http://github.com/sebastianbergmann/phpcpd" target="_blank">Projekt-Homepage von phpcpd</a>.<br />
<a name="phploc"></a></p>
<h2>phploc (PHP Lines of Code)</h2>
<p>Auch dieses kleine Tool ist von Sebastian Bergmann. Es erstellt einfache Codemetriken, wie die Anzahl der Zeilen, der Kommentar-Zeilen, der Klassen, und mehr.</p>
<p>Eine Beispiel-Ausgabe findet sich auch wieder auf der <a title="phploc" href="http://github.com/sebastianbergmann/phploc" target="_blank">Projekt-Homepage von phploc</a>.<br />
<a name="phpdepend"></a></p>
<h2>PHP Depend</h2>
<p><!-- 		@page { margin: 2cm } 		P { margin-bottom: 0.21cm } 		P.sdfootnote { margin-left: 0.5cm; text-indent: -0.5cm; margin-bottom: 0cm; font-size: 10pt } 		A:link { so-language: zxx } 		A.sdfootnoteanc { font-size: 57% } -->Komplexere Metriken, zum Beschreiben und Charakterisieren der Architektur eines Systems, erstellt <a title="PHP Depend" href="http://pdepend.org/" target="_blank">PHP Depend</a>, das Äquivalent zu <a title="JDepend" href="http://clarkware.com/software/JDepend.html" target="_blank">JDepend</a>.</p>
<p style="text-align:center;">Hauptbestandteil dieser Analyse ist die sog. „Overview Pyramid“ (weitere Informationen dazu: <a title="The overview pyramid in detail" href="http://www.iam.unibe.ch/~choose/Events/forum2006/Lanza_CHOOSE_06.pdf" target="_blank">&#8220;The overview pyramid in detail&#8221; </a>(PDF) oder <a title="Software-Metriken" href="http://www.trautwein.fh-aachen.de/Download/SWE/SWE_Ausarbeitungen_WS2008/A_Software-Metriken_2008_WS.pdf" target="_blank">&#8220;Software-Metriken&#8221;</a> (PDF)), die drei wichtige Aspekte (Größe/Komplexität, Kopplung und Verwendung der Vererbung) in einem übersichtlichen Format darstellt.<img class="aligncenter size-full wp-image-50" title="Overview Pyramid" src="http://whatwasitagain.files.wordpress.com/2009/05/pyramid.png?w=480" alt="Overview Pyramid" /></p>
<p>Die linke, untere Seite beschreibt Größe und Komplexität des Systems. Die Maßzahlen sind im einzelnen (jeweils von unten nach oben):</p>
<ul>
<li>Direkt erfassbare 	Kennzahlen:
<ul>
<li>CYCLO 		(<a title="Mc-Cabe-Metrik" href="http://de.wikipedia.org/wiki/McCabe-Metrik" target="_blank">zyklomatische Komplexität</a>): 		Maß für die Komplexität des Kontrollflusses eines Programms</li>
<li>LOC: Lines of Code</li>
<li>NOM: Number of 		Methods</li>
<li>NOC: Number of 		Classes</li>
<li>NOP: Number of 		Packages</li>
</ul>
</li>
<li>Abgeleitete 	Kennzahlen:
<ul>
<li>Intrinsic 		operation complexity (CYCLO/LOC)</li>
<li>Operation 		structuring (LOC/NOM)</li>
<li>Class structuring 		(NOM/NOC)</li>
<li>High-Level 		structuring (NOC/NOP)</li>
</ul>
</li>
</ul>
<p>Die abgeleiteten Kennzahlen ermöglichen Aussagen über die Granularität des Systems, zum Beispiel wieviele Methoden in einer Klasse vorkommen.</p>
<p>Die rechte, untere Seite der Pyramide beschreibt die Kopplung innerhalb des Systems.</p>
<ul>
<li>Direkt erfassbare 	Kennzahlen:
<ul>
<li>FANOUT: Zahl der aufgerufenen Klassen</li>
<li>CALLS: Zahl der Methoden-Aufrufe</li>
</ul>
</li>
</ul>
<ul>
<li>Abgeleitete 	Kennzahlen:
<ul>
<li>Coupling disperson 		(FANOUT/CALLS): Wie viele andere Operationen werden von einer 		Operation aus aufgerufen?</li>
<li>Coupling intensity 		(CALLS/NOM) : Wie stark sind die Klassen gekoppelt?</li>
</ul>
</li>
</ul>
<p>Der obere Teil der Pyramide gibt die folgenden, direkt erfassbaren Kennzahlen an, die die Verwendung von Vererbung charakterisieren:</p>
<ul>
<li>AHH: Average 	Hierarchy Height (Tiefe des Vererbungsbaums)</li>
<li>
<p class="sdfootnote">ANDC: Average Number 	of Derived Classes (durchschnittliche Anzahl der direkt abgeleiteten 	Klassen: Breite des Vererbungsbaums)</p>
</li>
</ul>
<p><a name="phpcs"></a></p>
<h2>PHP CodeSniffer</h2>
<p><!-- 		@page { margin: 2cm } 		P { margin-bottom: 0.21cm } --></p>
<p style="margin-bottom:0;"><a title="PHP CodeSniffer" href="http://pear.php.net/manual/en/package.php.php-codesniffer.intro.php" target="_blank">PHP CodeSniffer</a> dient dazu, den Code auf die Einhaltung von Coding-Standards hin zu überprüfen. Dabei wird folgendes untersucht:</p>
<ul>
<li>Vollständige Kommentar-Abdeckung</li>
<li>Einrückung / Groß- und Kleinschreibung</li>
<li>Namenskonventionen</li>
<li>Gestaltung von Kontrollstrukturen / Klammersetzung</li>
<li>und mehr</li>
</ul>
<p>Vorgefertigte Coding-Standards zum Beispiel von Zend oder PEAR können verwendet werden oder es können auch eigene Coding-Standards mit neuen Regeln angelegt werden. Wie dies funktioniert, wird hier beschrieben: <a title="PHP Code Sniffer - Parameter und eigene Regelsets" href="http://www.phphatesme.com/blog/tools/php-code-sniffer-parameter-und-eigene-regelsets-standard/" target="_blank">PHP Code Sniffer &#8211; Parameter und eigene Regelset</a>.<br />
<a name="phpunitcc"></a></p>
<h2>PHPUnit &#8211; Code Coverage</h2>
<p><!-- 		@page { margin: 2cm } 		P { margin-bottom: 0.21cm } --><a title="PHPUnit" href="http://www.phpunit.de/" target="_blank">PHPUnit</a> beinhaltet auch eine Funktionalität zur Überprüfung der Code-Abdeckung der Unit-Tests: <a title="Code Coverage" href="http://www.phpunit.de/manual/3.4/en/code-coverage-analysis.html" target="_blank">Code Coverage Analysis</a>.</p>
<p><!-- 		@page { margin: 2cm } 		P { margin-bottom: 0.21cm } -->Als Ausgabe wird ein übersichtlicher Report erstellt, aus dem auch genau ersichtlich wird, welche Codezeilen durch welche Tests abgedeckt wurden und welche gar nicht getestet wurden.</p>
<hr />Alle diese Tools lassen sich über den <a title="PEAR" href="http://pear.php.net/index.php" target="_blank">PEAR-Installer</a> installieren. Die jeweiligen Channels finden sich auf den Projekt-Homepages.</p>
<p>Wer sich näher mit der Qualitätssicherung in PHP beschäftigen will/muss, dem kann ich folgende Seiten empfehlen:</p>
<ul>
<li><a title="phpUnderControl" href="http://www.phpundercontrol.org" target="_blank">phpUnderControl</a>: Eine Erweiterung für <a title="CruiseControl" href="http://cruisecontrol.sourceforge.net/" target="_blank">CruiseControl</a>, die einige der oben genannten Tools unter einer Oberfläche vereint.</li>
<li><a title="Quality Assurance in PHP Projects" href="http://sebastian-bergmann.de/archives/857-Quality-Assurance-in-PHP-Projects.html" target="_blank">Quality Assurance in PHP Projects</a></li>
<li><a title="Statische Code-Analyse mit dem PHP Code Sniffer" href="http://www.phphatesme.com/blog/tools/statische-code-analyse-mit-dem-php-code-sniffer/" target="_blank">Statische Code-Analyse mit dem PHP Code Sniffer</a></li>
</ul>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/whatwasitagain.wordpress.com/42/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/whatwasitagain.wordpress.com/42/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/whatwasitagain.wordpress.com/42/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/whatwasitagain.wordpress.com/42/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/whatwasitagain.wordpress.com/42/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/whatwasitagain.wordpress.com/42/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/whatwasitagain.wordpress.com/42/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/whatwasitagain.wordpress.com/42/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/whatwasitagain.wordpress.com/42/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/whatwasitagain.wordpress.com/42/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/whatwasitagain.wordpress.com/42/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/whatwasitagain.wordpress.com/42/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/whatwasitagain.wordpress.com/42/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/whatwasitagain.wordpress.com/42/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=whatwasitagain.wordpress.com&amp;blog=4842555&amp;post=42&amp;subd=whatwasitagain&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://whatwasitagain.wordpress.com/2009/05/19/codemetriken-in-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a0121f9cc309e7dff279723b71e2ba85?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">whatwasitagain</media:title>
		</media:content>

		<media:content url="http://whatwasitagain.files.wordpress.com/2009/05/pyramid.png" medium="image">
			<media:title type="html">Overview Pyramid</media:title>
		</media:content>
	</item>
		<item>
		<title>KML-Dateien mit europäischen Jugendherbergen</title>
		<link>http://whatwasitagain.wordpress.com/2009/04/30/kml-dateien-mit-europaischen-jugendherbergen/</link>
		<comments>http://whatwasitagain.wordpress.com/2009/04/30/kml-dateien-mit-europaischen-jugendherbergen/#comments</comments>
		<pubDate>Thu, 30 Apr 2009 21:41:53 +0000</pubDate>
		<dc:creator>whatwasitagain</dc:creator>
				<category><![CDATA[Geo]]></category>
		<category><![CDATA[google maps]]></category>
		<category><![CDATA[jugendherbergen]]></category>
		<category><![CDATA[karte]]></category>
		<category><![CDATA[kml]]></category>
		<category><![CDATA[map]]></category>
		<category><![CDATA[youth hostel]]></category>

		<guid isPermaLink="false">http://whatwasitagain.wordpress.com/?p=30</guid>
		<description><![CDATA[Letztes Jahr mussten die KML-Dateien noch selber erstellt werden, mittlerweile bietet Hosting International auch Karten an, wobei die einzelnen Jugendherbergen über KML-Dateien eingeblendet werden. Alle Jugendherbergen in Deutschland werden auf dieser Karte angezeigt, dies ist die passende KML-Datei dazu. Für alle anderen Länder sind die URL&#8217;s ähnlich aufgebaut. Es muss einfach das Länderkürzel ersetzt werden. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=whatwasitagain.wordpress.com&amp;blog=4842555&amp;post=30&amp;subd=whatwasitagain&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://whatwasitagain.wordpress.com/2008/09/13/geocoding-mit-google-earth-karte-mit-allen-jugendherbergen-in-deutschland/">Letztes Jahr</a> mussten die KML-Dateien noch selber erstellt werden, mittlerweile bietet <a href="http://www.hihostels.com/web/index.de.htm">Hosting International</a> auch Karten an, wobei die einzelnen Jugendherbergen über KML-Dateien eingeblendet werden.</p>
<p>Alle Jugendherbergen in Deutschland werden auf dieser <a href="http://www.hihostels.com/dba/cmap-DE.de.htm?himap=Y">Karte</a> angezeigt, dies ist die passende <a href="http://www.hihostels.com/mapcoord/DE.de.kml">KML-Datei</a> dazu.</p>
<p>Für alle anderen Länder sind die URL&#8217;s ähnlich aufgebaut. Es muss einfach das Länderkürzel ersetzt werden.</p>
<p>Zum Beispiel für Frankreich (<strong>FR</strong>):<br />
URL zur Karte: <a href="http://www.hihostels.com/dba/cmap-FR.de.htm?himap=Y">http://www.hihostels.com/dba/cmap-<strong>FR</strong>.de.htm?himap=Y</a><br />
URL zur KML-Datei: <a href="http://www.hihostels.com/mapcoord/FR.de.kml">http://www.hihostels.com/mapcoord/<strong>FR</strong>.de.kml</a></p>
<p>Oder auch für Luxemburg (<strong>LU</strong>):<br />
URL zur Karte: <a href="http://www.hihostels.com/dba/cmap-LU.de.htm?himap=Y">http://www.hihostels.com/dba/cmap-<strong>LU</strong>.de.htm?himap=Y</a><br />
URL zur KML-Datei: <a href="http://www.hihostels.com/mapcoord/LU.de.kml">http://www.hihostels.com/mapcoord/<strong>LU</strong>.de.kml</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/whatwasitagain.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/whatwasitagain.wordpress.com/30/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/whatwasitagain.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/whatwasitagain.wordpress.com/30/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/whatwasitagain.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/whatwasitagain.wordpress.com/30/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/whatwasitagain.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/whatwasitagain.wordpress.com/30/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/whatwasitagain.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/whatwasitagain.wordpress.com/30/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/whatwasitagain.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/whatwasitagain.wordpress.com/30/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/whatwasitagain.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/whatwasitagain.wordpress.com/30/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=whatwasitagain.wordpress.com&amp;blog=4842555&amp;post=30&amp;subd=whatwasitagain&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://whatwasitagain.wordpress.com/2009/04/30/kml-dateien-mit-europaischen-jugendherbergen/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a0121f9cc309e7dff279723b71e2ba85?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">whatwasitagain</media:title>
		</media:content>
	</item>
		<item>
		<title>typeof() in C++</title>
		<link>http://whatwasitagain.wordpress.com/2009/01/31/typeof-in-cpp/</link>
		<comments>http://whatwasitagain.wordpress.com/2009/01/31/typeof-in-cpp/#comments</comments>
		<pubDate>Sat, 31 Jan 2009 12:05:29 +0000</pubDate>
		<dc:creator>whatwasitagain</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[typeid]]></category>
		<category><![CDATA[typeof]]></category>

		<guid isPermaLink="false">http://whatwasitagain.wordpress.com/?p=24</guid>
		<description><![CDATA[Wie findet man in C++ zur Laufzeit heraus, von welchem Typ eine Variable ist? Ist b jetzt vom Typ &#8220;Zeiger auf Integer&#8221; oder vom Typ &#8220;Integer&#8221;? Mit folgendem Aufruf hat man dies schnell geklärt: Siehe auch: typeid()<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=whatwasitagain.wordpress.com&amp;blog=4842555&amp;post=24&amp;subd=whatwasitagain&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Wie findet man in C++ zur Laufzeit heraus, von welchem Typ eine Variable ist?</p>
<p><pre class="brush: ruby;">int* a, b;</pre></p>
<p>Ist <em>b</em> jetzt vom Typ &#8220;Zeiger auf Integer&#8221; oder vom Typ &#8220;Integer&#8221;?</p>
<p>Mit folgendem Aufruf hat man dies schnell geklärt:</p>
<p><pre class="brush: ruby;">int* a, b;
std::cout &lt;&lt; (typeid(b) == typeid(int*)) &lt;&lt; std::endl;
//Ausgabe: 0
</pre></p>
<p>Siehe auch: <a href="http://en.wikipedia.org/wiki/Typeid" target="_blank">typeid()</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/whatwasitagain.wordpress.com/24/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/whatwasitagain.wordpress.com/24/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/whatwasitagain.wordpress.com/24/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/whatwasitagain.wordpress.com/24/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/whatwasitagain.wordpress.com/24/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/whatwasitagain.wordpress.com/24/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/whatwasitagain.wordpress.com/24/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/whatwasitagain.wordpress.com/24/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/whatwasitagain.wordpress.com/24/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/whatwasitagain.wordpress.com/24/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/whatwasitagain.wordpress.com/24/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/whatwasitagain.wordpress.com/24/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/whatwasitagain.wordpress.com/24/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/whatwasitagain.wordpress.com/24/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=whatwasitagain.wordpress.com&amp;blog=4842555&amp;post=24&amp;subd=whatwasitagain&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://whatwasitagain.wordpress.com/2009/01/31/typeof-in-cpp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a0121f9cc309e7dff279723b71e2ba85?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">whatwasitagain</media:title>
		</media:content>
	</item>
		<item>
		<title>Nautilus-Scripts: Geo-Referenzierte Photos in Google Maps/Earth anzeigen</title>
		<link>http://whatwasitagain.wordpress.com/2008/09/28/nautilus-scripts-geo-referenzierte-photos-in-google-mapsearth-anzeigen/</link>
		<comments>http://whatwasitagain.wordpress.com/2008/09/28/nautilus-scripts-geo-referenzierte-photos-in-google-mapsearth-anzeigen/#comments</comments>
		<pubDate>Sun, 28 Sep 2008 11:55:07 +0000</pubDate>
		<dc:creator>whatwasitagain</dc:creator>
				<category><![CDATA[Geo]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[geotag]]></category>
		<category><![CDATA[google earth]]></category>
		<category><![CDATA[google maps]]></category>
		<category><![CDATA[nautilus scripts]]></category>
		<category><![CDATA[photos]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://whatwasitagain.wordpress.com/?p=14</guid>
		<description><![CDATA[Um &#8220;mal eben&#8221; eine Auswahl an geo-referenzierten Photos aus dem Dateimanager Nautilus auf einer Karte in Google Maps/Earth anzeigen zu lassen, habe ich mir 2 kleine Bash-Skripte für Nautilus-Scripts geschrieben, die mir dabei behilflich sind. Nun selektiere ich einfach ein paar Photos, mache einen Rechtsklick und wähle &#8220;Skripte &#62; Open in Google Maps&#8221; aus. Im [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=whatwasitagain.wordpress.com&amp;blog=4842555&amp;post=14&amp;subd=whatwasitagain&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Um &#8220;mal eben&#8221; eine Auswahl an geo-referenzierten Photos aus dem Dateimanager Nautilus auf einer Karte in Google Maps/Earth anzeigen zu lassen, habe ich mir 2 kleine Bash-Skripte für <a href="http://wiki.ubuntuusers.de/Nautilus_Skripte" target="_blank">Nautilus-Scripts </a>geschrieben, die mir dabei behilflich sind.</p>
<p>Nun selektiere ich einfach ein paar Photos, mache einen Rechtsklick und wähle &#8220;Skripte &gt; Open in Google Maps&#8221; aus.</p>
<p><a href="http://whatwasitagain.files.wordpress.com/2008/09/nautilus_scripts_right_click.jpg"><img class="aligncenter size-thumbnail wp-image-15" title="Open in Google Maps/Earth" src="http://whatwasitagain.files.wordpress.com/2008/09/nautilus_scripts_right_click.jpg?w=480" alt="" /></a></p>
<p>Im Hintergrund werden jetzt die EXIF-Header der ausgewählten Photos mit Hilfe von <a title="Paket exiftool" href="http://packages.ubuntu.com/hardy/libimage-exiftool-perl" target="_blank">exiftool</a> auf Koordinaten untersucht. Es wird dann eine temporäre HTML-Seite in Firefox geöffnet, die eine Google Maps-Karte mit allen Photos enthält.</p>
<p><a href="http://whatwasitagain.files.wordpress.com/2008/09/nautilus_scripts_google_maps.jpg"><img class="aligncenter size-medium wp-image-16" title="Show in Google Maps" src="http://whatwasitagain.files.wordpress.com/2008/09/nautilus_scripts_google_maps.jpg?w=300&#038;h=207" alt="" width="300" height="207" /></a></p>
<p>Alternativ können die Photos auch in Google Earth angezeigt werden. Hierfür wird dann eine temporäre KML-Datei erstellt.</p>
<p>Und so lassen sich die Skripte einrichten:</p>
<p><span id="more-14"></span></p>
<p>Kopiere nachfolgenden Quelltext in einen Texteditor und speichere die Datei unter <em>&#8220;/home/{User}/.gnome2/nautilus-scripts/Open in GoogleMaps&#8221;</em> (ohne Dateiendung).</p>
<p><pre class="brush: ruby;"># Get the calling dir
CURRENTDIR=$(echo ${NAUTILUS_SCRIPT_CURRENT_URI})

# Path to the temporary KML file
KMLFILE=&quot;/tmp/$$.html&quot;

#Write KML - Header
echo &quot;&lt;!DOCTYPE html PUBLIC \&quot;-//W3C//DTD XHTML 1.0 Strict//EN\&quot; \&quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\&quot;&gt;&quot; &gt;&gt; $KMLFILE
echo &quot;&lt;html xmlns=\&quot;http://www.w3.org/1999/xhtml\&quot;&gt;&quot; &gt;&gt; $KMLFILE
echo &quot;&lt;head&gt;&quot; &gt;&gt; $KMLFILE
echo &quot;&lt;title&gt;Open in GoogleMaps&lt;/title&gt;&quot; &gt;&gt; $KMLFILE
echo &quot;&lt;meta http-equiv=\&quot;Content-Type\&quot; content=\&quot;text/html; charset=utf-8\&quot; /&gt;&quot; &gt;&gt; $KMLFILE
echo &quot;&quot; &gt;&gt; $KMLFILE
echo &quot;&lt;script src=\&quot;http://maps.google.com/maps?file=api&amp;v=2&amp;amp\&quot; type=\&quot;text/javascript\&quot;&gt;&quot; &gt;&gt; $KMLFILE
echo &quot;&lt;/script&gt;&quot; &gt;&gt; $KMLFILE
echo &quot;&lt;style type=\&quot;text/css\&quot;&gt;&quot; &gt;&gt; $KMLFILE
echo &quot;	html, body, #map {&quot; &gt;&gt; $KMLFILE
echo &quot;		width: 100%;&quot; &gt;&gt; $KMLFILE
echo &quot;		height: 100%;&quot; &gt;&gt; $KMLFILE
echo &quot;	}&quot; &gt;&gt; $KMLFILE
echo &quot;&quot; &gt;&gt; $KMLFILE
echo &quot;	body {&quot; &gt;&gt; $KMLFILE
echo &quot;		margin-top: 0px;&quot; &gt;&gt; $KMLFILE
echo &quot;		margin-right: 0px;&quot; &gt;&gt; $KMLFILE
echo &quot;		margin-left: 0px;&quot; &gt;&gt; $KMLFILE
echo &quot;		margin-bottom: 0px;&quot; &gt;&gt; $KMLFILE
echo &quot;	}&quot; &gt;&gt; $KMLFILE
echo &quot;&lt;/style&gt;&quot; &gt;&gt; $KMLFILE
echo &quot;&lt;/head&gt;&quot; &gt;&gt; $KMLFILE
echo &quot;&quot; &gt;&gt; $KMLFILE
echo &quot;&lt;body&gt;&quot; &gt;&gt; $KMLFILE
echo &quot;
&lt;div id=\&quot;map\&quot;&gt;&lt;/div&gt;
&quot; &gt;&gt; $KMLFILE
echo &quot;
&lt;div id=\&quot;footer\&quot;&gt;&quot; &gt;&gt; $KMLFILE
echo &quot;&quot; &gt;&gt; $KMLFILE
echo &quot;&lt;script type=\&quot;text/javascript\&quot;&gt;&quot; &gt;&gt; $KMLFILE
echo &quot;//&lt;![CDATA[&quot; &gt;&gt; $KMLFILE
echo &quot;var map;&quot; &gt;&gt; $KMLFILE
echo &quot;var markerOptions;&quot; &gt;&gt; $KMLFILE
echo &quot;var bounds;&quot; &gt;&gt; $KMLFILE
echo &quot;&quot; &gt;&gt; $KMLFILE
echo &quot;function addPoint(name, fileName, lat, lng) {&quot; &gt;&gt; $KMLFILE
echo &quot;	var latlng = new GLatLng(lat, lng);&quot; &gt;&gt; $KMLFILE
echo &quot;	var marker = new GMarker(latlng, markerOptions);&quot; &gt;&gt; $KMLFILE
echo &quot;	marker.value = 1;&quot; &gt;&gt; $KMLFILE
echo &quot;	GEvent.addListener(marker,\&quot;click\&quot;, function() {&quot; &gt;&gt; $KMLFILE
echo &quot;		var myHtml = \&quot;&lt;b&gt;\&quot; + name + \&quot;&lt;/b&gt;
&lt;img src=\\\&quot;\&quot; + fileName + \&quot;\\\&quot; width=\\\&quot;200\\\&quot; /&gt;\&quot;;&quot; &gt;&gt; $KMLFILE
echo &quot;        map.openInfoWindowHtml(latlng, myHtml);});&quot; &gt;&gt; $KMLFILE
echo &quot;	map.addOverlay(marker);&quot; &gt;&gt; $KMLFILE
echo &quot;	bounds.extend(latlng);&quot; &gt;&gt; $KMLFILE
echo &quot;}&quot; &gt;&gt; $KMLFILE
echo &quot;&quot; &gt;&gt; $KMLFILE
echo &quot;if (GBrowserIsCompatible()) {&quot; &gt;&gt; $KMLFILE
echo &quot;	map = new GMap2(document.getElementById(\&quot;map\&quot;));&quot; &gt;&gt; $KMLFILE
echo &quot;	map.setCenter(new GLatLng(0,0));&quot; &gt;&gt; $KMLFILE
echo &quot;	var mgr = new GMarkerManager(map);&quot; &gt;&gt; $KMLFILE
echo &quot;	map.setMapType(G_SATELLITE_MAP);&quot; &gt;&gt; $KMLFILE
echo &quot;	map.enableScrollWheelZoom();&quot; &gt;&gt; $KMLFILE
echo &quot;	map.addControl(new GLargeMapControl());&quot; &gt;&gt; $KMLFILE
echo &quot;	map.addControl(new GMapTypeControl());&quot; &gt;&gt; $KMLFILE
echo &quot;	map.addControl(new GScaleControl());&quot; &gt;&gt; $KMLFILE
echo &quot;	map.addControl(new GOverviewMapControl());&quot; &gt;&gt; $KMLFILE
echo &quot;&quot; &gt;&gt; $KMLFILE
echo &quot;	var photoIcon = new GIcon(G_DEFAULT_ICON);&quot; &gt;&gt; $KMLFILE
echo &quot;	photoIcon.image = \&quot;http://maps.google.com/mapfiles/kml/pal4/icon46.png\&quot;;&quot; &gt;&gt; $KMLFILE
echo &quot;	photoIcon.iconSize = new GSize(30, 30);&quot; &gt;&gt; $KMLFILE
echo &quot;	markerOptions = { icon:photoIcon };&quot; &gt;&gt; $KMLFILE
echo &quot;	bounds = new GLatLngBounds();&quot; &gt;&gt; $KMLFILE

PHOTOSADDED=1
#Loop selected files
while [ $# -gt 0 ]; do
	fileName=$1

	# Try to get GPS coordinates of this file
	KOORD=$(exiftool -n -f -p '$GPSLatitude,$GPSLongitude' &quot;${fileName}&quot;)

	#If the coordinates are invalid, they do look like this: &quot;-,-&quot;
	PRUEF=$(expr index &quot;$KOORD&quot; &quot;-&quot;)

	if [ $PRUEF = 0 ]
	then
		#This is a valid photo, so add to KML
		PHOTOSADDED=0

		echo &quot;	addPoint(\&quot;${fileName}\&quot;, \&quot;`pwd`/${fileName}\&quot;, ${KOORD});&quot; &gt;&gt; $KMLFILE

	fi
	shift
done

#Write KML - Footer
echo &quot;	map.setZoom(map.getBoundsZoomLevel(bounds));&quot; &gt;&gt; $KMLFILE
echo &quot;	map.setCenter(bounds.getCenter());&quot; &gt;&gt; $KMLFILE
echo &quot;   }&quot; &gt;&gt; $KMLFILE
echo &quot;//]]&gt;&quot; &gt;&gt; $KMLFILE
echo &quot;&lt;/script&gt;&quot; &gt;&gt; $KMLFILE
echo &quot;&lt;/div&gt;
&quot; &gt;&gt; $KMLFILE
echo &quot;&lt;/body&gt;&quot; &gt;&gt; $KMLFILE
echo &quot;&lt;/html&gt;&quot; &gt;&gt; $KMLFILE

if [ $PHOTOSADDED = 0 ]
then
	firefox &quot;${KMLFILE}&quot;
else
 	zenity --error --text &quot;Not one photo containing coordinates. Could not create KML file!&quot;
fi

</pre></p>
<p>Und das Skript für Google Earth kann unter dieser Datei gespeichert werden:<br />
<em>&#8220;/home/{User}/.gnome2/nautilus-scripts/Open in GoogleEarth&#8221;</em> (auch ohne Dateiendung)</p>
<p><pre class="brush: ruby;"># Get the calling dir
CURRENTDIR=$(echo ${NAUTILUS_SCRIPT_CURRENT_URI})

# Path to the temporary KML file
KMLFILE=&quot;/tmp/$$.kml&quot;

#Write KML - Header
echo &quot;&lt;?xml version=\&quot;1.0\&quot; encoding=\&quot;UTF-8\&quot;?&gt;&quot; &gt;&gt; $KMLFILE
echo &quot;&lt;kml xmlns=\&quot;http://earth.google.com/kml/2.1\&quot;&gt;&quot; &gt;&gt; $KMLFILE
echo &quot;&lt;Document&gt;&quot; &gt;&gt; $KMLFILE
echo &quot;	&lt;name&gt;KmlFile&lt;/name&gt;&quot; &gt;&gt; $KMLFILE
echo &quot;	&lt;Style id=\&quot;Photo\&quot;&gt;&quot; &gt;&gt; $KMLFILE
echo &quot;		&lt;IconStyle&gt;&quot; &gt;&gt; $KMLFILE
echo &quot;			&lt;Icon&gt;&quot; &gt;&gt; $KMLFILE
echo &quot;				&lt;href&gt;http://maps.google.com/mapfiles/kml/pal4/icon46.png&lt;/href&gt;&quot; &gt;&gt; $KMLFILE
echo &quot;			&lt;/Icon&gt;&quot; &gt;&gt; $KMLFILE
echo &quot;		&lt;/IconStyle&gt;&quot; &gt;&gt; $KMLFILE
echo &quot;	&lt;/Style&gt;&quot; &gt;&gt; $KMLFILE

PHOTOSADDED=1
#Loop selected files
while [ $# -gt 0 ]; do
	fileName=$1

	# Try to get GPS coordinates of this file
	KOORD=$(exiftool -n -f -p '$GPSLongitude,$GPSLatitude' &quot;${fileName}&quot;)

	#If the coordinates are invalid, they do look like this: &quot;-,-&quot;
	PRUEF=$(expr index &quot;$KOORD&quot; &quot;-&quot;)

	if [ $PRUEF = 0 ]
	then
		#This is a valid photo, so add to KML
		PHOTOSADDED=0

		echo &quot;&lt;Placemark&gt;&quot; &gt;&gt; $KMLFILE
		echo &quot;	&lt;name&gt;${fileName}&lt;/name&gt;&quot; &gt;&gt; $KMLFILE
		echo &quot;	&lt;description&gt;&lt;![CDATA[&lt;img src=\&quot;`pwd`/${fileName}\&quot; width=\&quot;200\&quot;/&gt;]]&gt;&lt;/description&gt;&quot; &gt;&gt; $KMLFILE
		echo &quot;	&lt;styleUrl&gt;#Photo&lt;/styleUrl&gt;&quot; &gt;&gt; $KMLFILE
		echo &quot;	&lt;Point&gt;&quot; &gt;&gt; $KMLFILE
		echo &quot;		&lt;coordinates&gt;${KOORD}&lt;/coordinates&gt;&quot; &gt;&gt; $KMLFILE
		echo &quot;	&lt;/Point&gt;&quot; &gt;&gt; $KMLFILE
		echo &quot;&lt;/Placemark&gt;&quot; &gt;&gt; $KMLFILE
	fi
	shift
done

#Write KML - Footer
echo &quot;&lt;/Document&gt;&quot; &gt;&gt; $KMLFILE
echo &quot;&lt;/kml&gt;&quot; &gt;&gt; $KMLFILE

if [ $PHOTOSADDED = 0 ]
then
	googleearth &quot;${KMLFILE}&quot;
else
 	zenity --error --text &quot;Not one photo containing coordinates. Could not create KML file!&quot;
fi
</pre></p>
<p>Nach einem Neustart von Nautilus werden diese zwei Skripte jetzt im Rechtsklick-Menü aufgeführt.</p>
<p>Zur Ausführung werden folgende Pakete/Programme benötigt:</p>
<ul>
<li>libimage-exiftool-perl</li>
<li>zenity</li>
<li>Firefox</li>
<li>Google Earth</li>
</ul>
<p>Die Skripte dürfen frei verwendet und weiter entwickelt werden.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/whatwasitagain.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/whatwasitagain.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/whatwasitagain.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/whatwasitagain.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/whatwasitagain.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/whatwasitagain.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/whatwasitagain.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/whatwasitagain.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/whatwasitagain.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/whatwasitagain.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/whatwasitagain.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/whatwasitagain.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/whatwasitagain.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/whatwasitagain.wordpress.com/14/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=whatwasitagain.wordpress.com&amp;blog=4842555&amp;post=14&amp;subd=whatwasitagain&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://whatwasitagain.wordpress.com/2008/09/28/nautilus-scripts-geo-referenzierte-photos-in-google-mapsearth-anzeigen/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a0121f9cc309e7dff279723b71e2ba85?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">whatwasitagain</media:title>
		</media:content>

		<media:content url="http://whatwasitagain.files.wordpress.com/2008/09/nautilus_scripts_right_click.jpg" medium="image">
			<media:title type="html">Open in Google Maps/Earth</media:title>
		</media:content>

		<media:content url="http://whatwasitagain.files.wordpress.com/2008/09/nautilus_scripts_google_maps.jpg?w=300" medium="image">
			<media:title type="html">Show in Google Maps</media:title>
		</media:content>
	</item>
		<item>
		<title>Geocoding mit Google Earth: Karte mit allen Jugendherbergen in Deutschland</title>
		<link>http://whatwasitagain.wordpress.com/2008/09/13/geocoding-mit-google-earth-karte-mit-allen-jugendherbergen-in-deutschland/</link>
		<comments>http://whatwasitagain.wordpress.com/2008/09/13/geocoding-mit-google-earth-karte-mit-allen-jugendherbergen-in-deutschland/#comments</comments>
		<pubDate>Sat, 13 Sep 2008 16:40:45 +0000</pubDate>
		<dc:creator>whatwasitagain</dc:creator>
				<category><![CDATA[Geo]]></category>
		<category><![CDATA[geocoding]]></category>
		<category><![CDATA[google earth]]></category>
		<category><![CDATA[google maps]]></category>
		<category><![CDATA[kml]]></category>
		<category><![CDATA[map]]></category>
		<category><![CDATA[youth hostel]]></category>

		<guid isPermaLink="false">http://whatwasitagain.wordpress.com/?p=4</guid>
		<description><![CDATA[Update: Mittlerweile bietet Hosting International auch direkt Karten an, siehe KML-Dateien mit europäischen Jugendherbergen. Beim Planen einer Tour in die Provence mit GoogleMaps ist mir aufgefallen, dass dafür gar keine Layer/Karten mit allen Jugendherbergen zu finden sind. Deshalb habe ich mir heute auf die Schnelle ein kleines Java-Programm geschrieben, dass alle Jugendherbergen von Hostelling International [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=whatwasitagain.wordpress.com&amp;blog=4842555&amp;post=4&amp;subd=whatwasitagain&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<blockquote><p><strong>Update:</strong></p>
<p>Mittlerweile bietet Hosting International auch direkt Karten an, siehe <a href="http://whatwasitagain.wordpress.com/2009/04/30/kml-dateien-mit-europaischen-jugendherbergen/">KML-Dateien mit europäischen Jugendherbergen</a>.</p></blockquote>
<p>Beim Planen einer Tour in die Provence mit GoogleMaps ist mir aufgefallen, dass dafür gar keine Layer/Karten mit allen Jugendherbergen zu finden sind.</p>
<p>Deshalb habe ich mir heute auf die Schnelle ein kleines Java-Programm geschrieben, dass alle Jugendherbergen von <a href="http://www.hihostels.com/dba/country-DE.de.htm" target="_blank">Hostelling International</a> heraussucht und die Adressen in eine KML-Datei schreibt. Über GoogleEarth habe ich diese Adressen dann geokodieren lassen.</p>
<p>Hochgeladen in GoogleMaps kann diese Karte nun frei verwendet werden:</p>
<p><a href="http://maps.google.com/maps/ms?hl=de&amp;ie=UTF8&amp;oe=UTF8&amp;msa=0&amp;msid=104273562520030596815.000456ca2b46c2d1c864a&amp;ll=51.440313,10.744629&amp;spn=6.548818,13.601074&amp;z=6" target="_blank">Karte mit allen Jugendherbergen in Deutschland</a> (<a href="http://maps.google.com/maps/ms?hl=de&amp;ie=UTF8&amp;oe=UTF8&amp;msa=0&amp;output=nl&amp;msid=104273562520030596815.000456ca2b46c2d1c864a" target="_blank">KML</a>)<a href="http://maps.google.com/maps/ms?hl=de&amp;ie=UTF8&amp;oe=UTF8&amp;msa=0&amp;msid=104273562520030596815.000456ca2b46c2d1c864a&amp;ll=51.440313,10.744629&amp;spn=6.548818,13.601074&amp;z=6" target="_blank"><br />
</a></p>
<p><a href="http://maps.google.com/maps/ms?hl=de&amp;ie=UTF8&amp;oe=UTF8&amp;msa=0&amp;msid=104273562520030596815.000456ca2b46c2d1c864a&amp;ll=51.440313,10.744629&amp;spn=6.548818,13.601074&amp;z=6" target="_blank"><img class="alignnone size-full wp-image-5" title="Jugendherbergen in GoogleMaps" src="http://whatwasitagain.files.wordpress.com/2008/09/google_maps_jh_de.jpg?w=480" alt=""   /></a></p>
<p>Und dies ist die Karte für Frankreich:</p>
<p><a href="http://maps.google.com/maps/ms?hl=de&amp;ie=UTF8&amp;oe=UTF8&amp;msa=0&amp;msid=104273562520030596815.000456ca05fcf07156d00" target="_blank">Karte mit allen Jugendherbergen in Frankreich</a> (<a href="http://maps.google.com/maps/ms?hl=de&amp;ie=UTF8&amp;oe=UTF8&amp;msa=0&amp;output=nl&amp;msid=104273562520030596815.000456ca05fcf07156d00" target="_blank">KML</a>)</p>
<p>Da in GoogleMaps nur die Jugendherbergen auf der Karte angezeigt werden, die links auf der im Inhaltsverzeichnis ausgewählten Seite aufgelistet sind, schaut man sich es besser in GoogleEarth über die KML-Dateien an.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/whatwasitagain.wordpress.com/4/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/whatwasitagain.wordpress.com/4/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/whatwasitagain.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/whatwasitagain.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/whatwasitagain.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/whatwasitagain.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/whatwasitagain.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/whatwasitagain.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/whatwasitagain.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/whatwasitagain.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/whatwasitagain.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/whatwasitagain.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/whatwasitagain.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/whatwasitagain.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/whatwasitagain.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/whatwasitagain.wordpress.com/4/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=whatwasitagain.wordpress.com&amp;blog=4842555&amp;post=4&amp;subd=whatwasitagain&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://whatwasitagain.wordpress.com/2008/09/13/geocoding-mit-google-earth-karte-mit-allen-jugendherbergen-in-deutschland/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a0121f9cc309e7dff279723b71e2ba85?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">whatwasitagain</media:title>
		</media:content>

		<media:content url="http://whatwasitagain.files.wordpress.com/2008/09/google_maps_jh_de.jpg" medium="image">
			<media:title type="html">Jugendherbergen in GoogleMaps</media:title>
		</media:content>
	</item>
	</channel>
</rss>
