Home >
Here's a silly post that contains a trick combining graphics filters with Google maps for some interesting effects. They don't necessarily make it easier to read the maps, nor do they have a lot of value, but they look interesting, and are fun to play with.
I can't claim this idea as my own. I just randomly stumbled across this post on axismaps.com, and figured I'd throw together a Flex example showing how to do it.
The effects are applied directly to the map tiles, not the entire map component, so all of the other controls still look like normal. Let's take a look at it in action... You can either select a preset, or adjust the slider values to change the filters applied to the map instance.
The original post has some other interesting effects which can be achieved through various permutations of the input array for the ColorMatrixFilter instance. This example is pretty basic, and only manipulates the red, green, and blue channels independently.
Here's how to make it all work. It's really pretty simple. This example just creates color matrix filters and applies them to the mapping components. I started with the samples for the Google Maps API, and just started applying different filters.
___________________________________
Andrew Trice
Principal Architect
Cynergy Systems
http://www.cynergysystems.com
I can't claim this idea as my own. I just randomly stumbled across this post on axismaps.com, and figured I'd throw together a Flex example showing how to do it.
The effects are applied directly to the map tiles, not the entire map component, so all of the other controls still look like normal. Let's take a look at it in action... You can either select a preset, or adjust the slider values to change the filters applied to the map instance.
The original post has some other interesting effects which can be achieved through various permutations of the input array for the ColorMatrixFilter instance. This example is pretty basic, and only manipulates the red, green, and blue channels independently.
Here's how to make it all work. It's really pretty simple. This example just creates color matrix filters and applies them to the mapping components. I started with the samples for the Google Maps API, and just started applying different filters.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:maps="com.google.maps.*"
xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute">
<mx:Style>
Application {
backgroundColor: #999999;
themeColor: #cccc00;
}
Panel {
borderColor: #cccccc;
borderAlpha: 0.85;
borderThicknessLeft: 1;
borderThicknessTop: 0;
borderThicknessBottom: 1;
borderThicknessRight: 1;
cornerRadius: 3;
backgroundAlpha: 0.92;
highlightAlphas: 0.26, 0;
}
</mx:Style>
<mx:Script>
<![CDATA[
import com.google.maps.services.ClientGeocoder;
import mx.controls.Alert;
import com.google.maps.MapMouseEvent;
import com.google.maps.services.GeocodingEvent;
import com.google.maps.controls.MapTypeControl;
import com.google.maps.controls.PositionControl;
import com.google.maps.controls.ZoomControl;
import com.google.maps.LatLng;
import com.google.maps.Map;
import com.google.maps.MapEvent;
import com.google.maps.MapType;
private var geocoder : ClientGeocoder;
private function onMapReady(event:Event):void
{
map.setCenter( new LatLng( 38.895108,-77.035961 ), 14, MapType.NORMAL_MAP_TYPE);
map.addControl(new ZoomControl());
map.addControl(new PositionControl());
map.addControl(new MapTypeControl());
geocoder = new ClientGeocoder();
geocoder.addEventListener( GeocodingEvent.GEOCODING_SUCCESS, onGeocodeSuccess);
geocoder.addEventListener( GeocodingEvent.GEOCODING_FAILURE, onGeocodeFault );
}
private function doGeocode():void
{
geocoder.geocode(searchString.text);
}
private function onGeocodeSuccess( event : GeocodingEvent ) : void
{
var placemarks:Array = event.response.placemarks;
if (placemarks.length > 0)
map.setCenter(placemarks[0].point);
}
private function onGeocodeFault( event : GeocodingEvent ) : void
{
Alert.show("Geocoding failed");
trace(event);
trace(event.status);
}
private function setFilter() : void
{
var filter : ColorMatrixFilter = new ColorMatrixFilter();
var matrix:Array = new Array();
matrix = matrix.concat([r.value, 0, 0, 0, 0]); // red
matrix = matrix.concat([0, g.value, 0, 0, 0]); // green
matrix = matrix.concat([0, 0, b.value, 0, 0]); // blue
matrix = matrix.concat([0, 0, 0, a.value, 0]); // alpha
filter.matrix = matrix;
setMapFilter( filter );
}
private function setFilterPreset() : void
{
switch ( preset.selectedIndex )
{
case 1: // grayscale
var red:Number = 0.3086; // luminance contrast value for red
var green:Number = 0.694; // luminance contrast value for green
var blue:Number = 0.0820; // luminance contrast value for blue
var cmf:ColorMatrixFilter = new ColorMatrixFilter([red, green, blue, 0, 0,
red, green, blue, 0, 0,
red, green, blue, 0, 0,
0, 0, 0, 1, 0]);
setMapFilter( cmf );
return;
break;
case 2: // Blood
r.value = .97;
g.value = .05;
b.value = .05;
a.value = .9;
break;
case 3: // Green
r.value = .05;
g.value = .65;
b.value = .05;
a.value = .9;
break;
case 4: // Yellow
r.value = .95;
g.value = .95;
b.value = .05;
a.value = .9;
break;
default:
r.value = 1;
g.value = 1;
b.value = 1;
a.value = 1;
break;
}
setFilter();
}
private function setMapFilter( filter : ColorMatrixFilter ) : void
{
var s1:Sprite = map.getChildAt(1) as Sprite;
var s2:Sprite = s1.getChildAt(0) as Sprite;
s2.filters = [ filter ];
}
]]>
</mx:Script>
<mx:ApplicationControlBar dock="true" defaultButton="{ searchButton }">
<mx:TextInput id="searchString" width="150" />
<mx:Button click="doGeocode()" label="Find!" id="searchButton" />
</mx:ApplicationControlBar>
<maps:Map id="map" mapevent_mapready="onMapReady(event)"
width="100%" height="100%" key="API key goes here"/>
<mx:Panel
top="50" right="10"
width="250" height="200"
layout="vertical"
title="Map Effects">
<mx:Form width="100%" height="100%">
<mx:FormItem label="preset:">
<mx:ComboBox id="preset"
dataProvider="[ 'Normal', 'Gray Scale', 'Blood', 'Green', 'Yellow' ]"
change="setFilterPreset()" />
</mx:FormItem>
<mx:FormItem label="red:">
<mx:HSlider
minimum="0" maximum="2" value="1"
id="r" change="setFilter()"
liveDragging="true" width="140"/>
</mx:FormItem>
<mx:FormItem label="green:">
<mx:HSlider
minimum="0" maximum="2" value="1"
id="g" change="setFilter()"
liveDragging="true" width="140"/>
</mx:FormItem>
<mx:FormItem label="blue:">
<mx:HSlider
minimum="0" maximum="2" value="1"
id="b" change="setFilter()"
liveDragging="true" width="140"/>
</mx:FormItem>
<mx:FormItem label="alpha:">
<mx:HSlider
minimum="0" maximum="1" value="1"
id="a" change="setFilter()"
liveDragging="true" width="140"/>
</mx:FormItem>
</mx:Form>
</mx:Panel>
</mx:Application>
Andrew Trice
Principal Architect
Cynergy Systems
http://www.cynergysystems.com




Facebook Application Development
One good use of such a thing is accessibility concerns for those who can't see colours properly. Very cool stuff!
Nice. I like grayscale. For me it makes the map much easier to read.
Nice one it can realy improve accessibility
Thanks, Andrew, great post!
Since developers can potentially create un-usable maps with this hack, we are currently requesting that all developers re-coloring their maps formally request permission:
https://spreadsheets.google.com/viewform?formkey=cm0zMDkzOHZWMjJneEl2RVdkNFZRb0E6MA
We've approved most of the uses so far, we just want to make sure users are getting a good experience.
Google's mapping services are chock full of secrets. For a while Google Moon had a really great one.
http://www.googleeastereggs.com/
Dear sir,
I have just tried your example in flex. but does not work. I dont know why filter is not applying on map. please help me.
I got my answer. I done little change in your code. I have changed setMapFilter function. I removed all three lines and just set "map.filters" property directly. It works fine.
I hope it will helpful to others also !
Hitesh, this will also change the colors on the Google logo overlay. With the logic described above, it will not change the overlays.