Posts tagged ‘Tilelayer’

July 18, 2011

Rendering Text Labels with Custom Fonts in Mapnik

The default font family used for rendering text labels on maps created by Mapnik (and the one shipped with it) is Deja Vu. Deja Vu Sans Book is a pretty nice font, and can be seen, for example, in all the labels used on Open Street Map:

image

So what if you want to render text onto a custom tile overlay using a different font?

  • Perhaps you’d like to create a custom tile layer using image labels to match Google Maps?
  • Or how about going for a Bing Maps feel with image labels?

To do so, first you need to register the location of the directory containing the fonts you want to use. For example, to make all the installed Windows fonts available to Mapnik, add the following to the top of your python render script:

mapnik.register_fonts('c:/windows/fonts/')

Mapnik needs to reference these fonts by their font name (not by filename, for example); To find out the correct name to use for each font, once you’ve registered your custom fonts directory you can call the following:

for face in mapnik.FontEngine.face_names(): print face

On a fairly vanilla installation of Window 7, this gave me a list of available fonts as follows:

  • Aharoni Bold
  • Andalus Regular
  • Andy Bold
  • Angsana New Bold
  • Angsana New Bold Italic
  • Angsana New Italic
  • Angsana New Regular
  • AngsanaUPC Bold
  • AngsanaUPC Bold Italic
  • AngsanaUPC Italic
  • AngsanaUPC Regular
  • Aparajita Bold
  • Aparajita Bold Italic
  • Aparajita Italic
  • Aparajita Regular
  • Arabic Typesetting Regular
  • Arial Black
  • Arial Bold
  • Arial Bold Italic
  • Arial Italic
  • Arial Regular
  • Browallia New Bold
  • Browallia New Bold Italic
  • Browallia New Italic
  • Browallia New Regular
  • BrowalliaUPC Bold
  • BrowalliaUPC Bold Italic
  • BrowalliaUPC Italic
  • BrowalliaUPC Regular
  • Buxton Sketch Regular
  • Calibri Bold
  • Calibri Bold Italic
  • Calibri Italic
  • Calibri Regular
  • Candara Bold
  • Candara Bold Italic
  • Candara Italic
  • Candara Regular
  • Comic Sans MS Bold
  • Comic Sans MS Regular
  • Consolas Bold
  • Consolas Bold Italic
  • Consolas Italic
  • Consolas Regular
  • Constantia Bold
  • Constantia Bold Italic
  • Constantia Italic
  • Constantia Regular
  • Corbel Bold
  • Corbel Bold Italic
  • Corbel Italic
  • Corbel Regular
  • Cordia New Bold
  • Cordia New Bold Italic
  • Cordia New Italic
  • Cordia New Regular
  • CordiaUPC Bold
  • CordiaUPC Bold Italic
  • CordiaUPC Italic
  • CordiaUPC Regular
  • Courier New Bold
  • Courier New Bold Italic
  • Courier New Italic
  • Courier New Regular
  • DFKai-SB Regular
  • DRMS T1 Regular
  • DaunPenh Regular
  • David Bold
  • David Regular
  • DengXian Bold
  • DengXian Regular
  • DilleniaUPC Bold
  • DilleniaUPC Bold Italic
  • DilleniaUPC Italic
  • DilleniaUPC Regular
  • DokChampa Regular
  • Ebrima Bold
  • Ebrima Regular
  • Estrangelo Edessa Regular
  • EucrosiaUPC Bold
  • EucrosiaUPC Bold Italic
  • EucrosiaUPC Italic
  • EucrosiaUPC Regular
  • Euphemia Regular
  • FangSong Regular
  • FrankRuehl Regular
  • Franklin Gothic Medium Italic
  • Franklin Gothic Medium Regular
  • FreesiaUPC Bold
  • FreesiaUPC Bold Italic
  • FreesiaUPC Italic
  • FreesiaUPC Regular
  • Gabriola Regular
  • Gautami Bold
  • Gautami Regular
  • Georgia Bold
  • Georgia Bold Italic
  • Georgia Italic
  • Georgia Regular
  • Gisha Bold
  • Gisha Regular
  • Impact Regular
  • IrisUPC Bold
  • IrisUPC Bold Italic
  • IrisUPC Italic
  • IrisUPC Regular
  • Iskoola Pota Bold
  • Iskoola Pota Regular
  • JasmineUPC Bold
  • JasmineUPC Bold Italic
  • JasmineUPC Italic
  • JasmineUPC Regular
  • Jing Jing Regular
  • KaiTi Regular
  • Kalinga Bold
  • Kalinga Regular
  • Kartika Bold
  • Kartika Regular
  • Khmer UI Bold
  • Khmer UI Regular
  • KodchiangUPC Bold
  • KodchiangUPC Bold Italic
  • KodchiangUPC Italic
  • KodchiangUPC Regular
  • Kokila Bold
  • Kokila Bold Italic
  • Kokila Italic
  • Kokila Regular
  • Kootenay Regular
  • Lao UI Bold
  • Lao UI Regular
  • Latha Bold
  • Latha Regular
  • Leelawadee Bold
  • Leelawadee Regular
  • Levenim MT Bold
  • Levenim MT Regular
  • LilyUPC Bold
  • LilyUPC Bold Italic
  • LilyUPC Italic
  • LilyUPC Regular
  • Lindsey Regular
  • Lucida Console Regular
  • Lucida Sans Unicode Regular
  • MV Boli Regular
  • Malgun Gothic Bold
  • Malgun Gothic Regular
  • Mangal Bold
  • Mangal Regular
  • Marlett Regular
  • Microsoft Himalaya Regular
  • Microsoft JhengHei Bold
  • Microsoft JhengHei Regular
  • Microsoft MHei Bold
  • Microsoft MHei Regular
  • Microsoft NeoGothic Bold
  • Microsoft NeoGothic Regular
  • Microsoft New Tai Lue Bold
  • Microsoft New Tai Lue Regular
  • Microsoft PhagsPa Bold
  • Microsoft PhagsPa Regular
  • Microsoft Sans Serif Regular
  • Microsoft Tai Le Bold
  • Microsoft Tai Le Regular
  • Microsoft Uighur Regular
  • Microsoft YaHei Bold
  • Microsoft YaHei Regular
  • Microsoft Yi Baiti Regular
  • Miramonte Bold
  • Miramonte Regular
  • Miriam Fixed Regular
  • Miriam Regular
  • Moire Bold
  • Moire ExtraBold
  • Moire Light
  • Moire Regular
  • Mongolian Baiti Regular
  • MoolBoran Regular
  • Motorwerk Regular
  • Narkisim Regular
  • Nina Bold
  • Nina Regular
  • Nyala Regular
  • Palatino Linotype Bold
  • Palatino Linotype Bold Italic
  • Palatino Linotype Italic
  • Palatino Linotype Regular
  • Pericles Light
  • Pericles Regular
  • Pescadero Bold
  • Pescadero Regular
  • Plantagenet Cherokee Regular
  • Raavi Bold
  • Raavi Regular
  • Rod Regular
  • Sakkal Majalla Bold
  • Sakkal Majalla Regular
  • Segoe Condensed Bold
  • Segoe Condensed Regular
  • Segoe Marker Regular
  • Segoe Print Bold
  • Segoe Print Regular
  • Segoe Script Bold
  • Segoe Script Regular
  • Segoe UI Bold
  • Segoe UI Bold Italic
  • Segoe UI Italic
  • Segoe UI Light
  • Segoe UI Regular
  • Segoe UI Semibold
  • Segoe UI Symbol Regular
  • Segoe WP Black
  • Segoe WP Bold
  • Segoe WP Light
  • Segoe WP Regular
  • Segoe WP SemiLight
  • Segoe WP Semibold
  • Shonar Bangla Bold
  • Shonar Bangla Regular
  • Shruti Bold
  • Shruti Regular
  • SimHei Regular
  • SimSun-ExtB Regular
  • Simplified Arabic Bold
  • Simplified Arabic Fixed Regular
  • Simplified Arabic Regular
  • SketchFlow Print Regular
  • Sylfaen Regular
  • Symbol Regular
  • Tahoma Bold
  • Tahoma Regular
  • Times New Roman Bold
  • Times New Roman Bold Italic
  • Times New Roman Italic
  • Times New Roman Regular
  • Traditional Arabic Bold
  • Traditional Arabic Regular
  • Transport Medium
  • Trebuchet MS Bold
  • Trebuchet MS Bold Italic
  • Trebuchet MS Italic
  • Trebuchet MS Regular
  • Tunga Bold
  • Tunga Regular
  • Utsaah Bold
  • Utsaah Bold Italic
  • Utsaah Italic
  • Utsaah Regular
  • Vani Bold
  • Vani Regular
  • Verdana Bold
  • Verdana Bold Italic
  • Verdana Italic
  • Verdana Regular
  • Vijaya Bold
  • Vijaya Regular
  • Vrinda Bold
  • Vrinda Regular
  • Webdings Regular
  • Wingdings Regular
  • Yu Gothic Bold
  • Yu Gothic Regular

To use one of these fonts, set the TextSymbolizer face_name attribute in the style applied to your layer to the name of whatever font you want.

For example, here’s a style with default Deja Vu Sans Book text labels:

<Style name="text">
  <Rule>
    <TextSymbolizer
      name="NAME"
      placement="point"
      fill="black"
      size="18"
      face_name="Deja Vu Sans Book"
      min_distance="10"
      avoid_edges="false"
      allow_overlap="true"
      spacing="5"
      wrap_width="20"
      halo_radius="1"
      halo_fill="#DFDBE3"
    /> 
  </Rule>
</Style>

and this is the map it creates:

image

And here’s the same map rendered with, oh I don’t know, say Comic Sans MS Regular style (don’t ever, ever do this! Maybe unless you’re creating a map of how to get to a children’s party…)

<Style name="text">
  <Rule>
    <TextSymbolizer
      name="NAME"
      placement="point"
      fill="black"
      size="18"
      face_name="Comic Sans MS Regular"
      min_distance="10"
      avoid_edges="false"
      allow_overlap="true"
      spacing="5"
      wrap_width="20"
      halo_radius="1"
      halo_fill="#DFDBE3"
    /> 
  </Rule>
</Style>

which leads to this:

image

I’m not saying it’s an improvement! But now you know how to do it…

Tags: ,
June 14, 2011

Geo-referencing and Tile-cutting Raster Imagery

Just as there are many different formats in which vector spatial data may be represented: Well-Known Text (WKT), Well-Known Binary (WKB), Geography Markup Language (GML), and Keyhole Markup Lanuage (KML), to name but a few – so too are there many different formats of raster spatial data.  In fact, almost any image format can be used to encode raster spatial data – since each pixel in an image naturally corresponds to an X,Y location in a raster grid. Any regular BMP, GIF, PNG, JPG, or TIFF image file can therefore be used to store spatial data, so long as the real-world coordinates corresponding to the pixels in each corner of the image are known (and thus the coordinates of each other pixel in the image can be determined). The process of assigning coordinates from a spatial reference system to a raster image is known as geo-referencing.

Some dedicated spatial raster formats, such as GeoTIFF, encode coordinate metadata along with the image data in a single file. However, the raster images used by Open Street Maps, Bing Maps, and Google Maps don’t use GeoTIFFs – they are formed from a series of 256px x 256px tiles saved as regular PNG and JPG images. The metadata describing the geographic extent of each tile is encoded entirely in the filename, which, in Bing Maps, uses the quadkey numbering system as described here.

For example, the following tile shows the Bing Maps road map style tile for quadkey 031311, retrieved from http://ecn.t1.tiles.virtualearth.net/tiles/r031311.png?g=685&mkt=en-us

image

Knowing nothing but the quadkey number, 031311, and the formulas in the MSDN article linked above, I can calculate that the exact geographic extent of features shown on this tile lie from longitude of –5.625 to 0, and latitude between 52.4827802220782 and 55.7765730186677. Like all Bing Maps tiles, they are projected using the Spherical Mercator projection.

Here’s another tile – this time 120200223:

image

Once again, I can immediately determine from the quadkey that the extent of this tile has longitude ranging from 0.703125 to 1.40625 and latitude from 52.4827802220782 to 52.9089020477703.

The quadkey system is quite beautiful in its simplicity and efficiency. There are, of course, some limitations with this sort of tiling system – all raster data must be represented using the same projection, and every tile must be regularly-sized, for example, but these limitations are offset by the ease with which it’s possible to place any tile at any zoom level at the correct position on the map with minimum amount of coding.

Preparing Custom Tiles

To get your own raster data into Bing Maps (such as a digitized map or floor plan), you need to prepare a series of individual quadkey tile images following the structure outlined above. Applications such as Safe FME and Microsoft MapCruncher provide the ability to prepare raster images for use as background tile layers in Bing Maps (or Google Maps), or you can write your own script to do so. The process is generally known as “tile-cutting”, and the steps are described below:

1.) First, start out with a source image. Here’s John Snow’s famous map of the Cholera outbreak that occurred in Broad Street in London, 1854:

image

2.) Georeference the image, by assigning coordinates to corresponding pixel positions in the image. If the image is not already in the correct projection, it might need to be warped to bring features into line with the Mercator projection as used by Bing Maps. The image below shows the interface provided by Mapcruncher for placing reference points in the source image (left hand pane) and Bing Maps (right hand pane):

image

3.) The geo-referenced, transformed image must then be cut into a series of 256px x 256px tiles at different levels of magnification, numbered according to quadkey. For example, the tile below shows a single tile from zoom level 16 of the above image (quadkey 0313131311122330):

0313131311122330

4.) Finally, create a tilelayer that references the set of quadkey tile images. Assuming that the tiles are all saved in the same directory, this is as simple as adding the following lines of javascript. the Bing Maps v7 control will expand the {quadkey} placeholder to the appropriate quadkey filename for each tile request:

// Define the tile source
var tileSource = new Microsoft.Maps.TileSource({
  uriConstructor: 'http://example.com/pathtoyourtiles/{quadkey}.png'
});

// Construct a tile layer based on the tile source
var tilelayer = new Microsoft.Maps.TileLayer({
  mercator: tileSource,
  opacity: 1.0,
  visible: true,
  zIndex: 1
});

// Place the layer onto the map
map.entities.push(tilelayer);

The result

Once the tilelayer is added to the map, whenever a part of that tilelayer comes into view Bing Maps will automatically request and stitch together the appropriate tile images and overlay them at the appropriate position on the map.

The screenshot below shows the result of overlaying Jon Snow’s Cholera map onto a modern day map of London using Bing Maps’ default road map style using the steps described above. Notice how well the roads that cross the edges of the tile layer line up – John Snow was not only the father of epidemiology, but also a highly talented cartographer:

image

February 19, 2011

Using ESRI Base Map Tile Layers in Bing Maps

( UPDATE: For loading ESRI Base Map Tiles on the AJAX v7.0 control, please go to http://alastaira.wordpress.com/2011/04/01/displaying-open-street-map-and-esri-tiles-on-bing-maps-ajax-v7/ )

I received an email this morning from the ESRI announcements mailing list stating that “ArcGIS Online basemaps published and hosted by Esri are now freely available to all users regardless of commercial, noncommercial, internal, or external use.”.

This is a nice surprise – it’s always useful to have a greater choice of tile styles on which to build your map, and ESRI have a nice selection of alternative map types. So, I decided to test them out by creating some ESRI tile layers in the Bing Maps Silverlight control.

The basic method of creating a new tilelayer using the Bing Maps Silverlight control is to define a new custom class in your .xaml.cs code file that inherits from the Microsoft.Maps.MapControl.TileSource class. You set the base of this class to represent the URL template of the tiles that will be used to build this layer. Then, by overriding the GetUri() method of this class, you insert the parameters corresponding to the x, y, and zoomlevel of each requested tile image from this tilelayer. For example, the following code demonstrates how to construct a class based on the ESRI topo world map tiles:

public class ESRITileSource : Microsoft.Maps.MapControl.TileSource
{
 public ESRITileSource() : base("http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{0}/{1}/{2}")
 { }

public override Uri GetUri(int x, int y, int zoomLevel)
 {
 return new Uri(String.Format(this.UriFormat, zoomLevel, y, x));
 }
}

Then, in your .xaml file, hide the default Bing Maps base tiles by specifying the MercatorMode of the map, and create a new tilelayer based on the custom tilelayer class instead:

<m:Map x:Name="Map1" Grid.Row="1" Grid.Column="1" Center="55,-2" ZoomLevel="6" CredentialsProvider="{StaticResource MyCredentials}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
 <!-- Do Not Display Bing Maps base layer -->
 <m:Map.Mode>
 <mcore:MercatorMode></mcore:MercatorMode>
 </m:Map.Mode>
 <!-- Add ESRI Tile Layer -->
 <m:Map.Children>
 <m:MapTileLayer>
 <m:MapTileLayer.TileSources>
 <local:ESRITileSource></local:ESRITileSource>
 </m:MapTileLayer.TileSources>
 </m:MapTileLayer>
 </m:Map.Children>
</m:Map>

Using this method, I tried out a few of the different ESRI styles, as shown below:

World Topography

URL Template: http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{0}/{1}/{2}

image

World Shaded Relief

URL Template: http://services.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer/tile/{0}/{1}/{2}

image

DeLorme World Basemap

URL Template: http://server.arcgisonline.com/ArcGIS/rest/services/Specialty/DeLorme_World_Base_Map/MapServer/tile/{0}/{1}/{2}

image

World Physical Map

URL Template: http://services.arcgisonline.com/ArcGIS/rest/services/World_Physical_Map/MapServer/tile/{0}/{1}/{2}

image

There’s plenty more map styles, including demographic maps (US only), specialist maritime maps etc. – see http://www.esri.com/software/arcgis/arcgisonline/standard-maps.html for more details.

Follow

Get every new post delivered to your Inbox.

Join 53 other followers