<?xml version="1.0" encoding="utf-8"?>
<!--
  Copyright 2009 James Richards
  Licensed under the Creative Commons Attribution 3.0 United States License:
    http://creativecommons.org/licenses/by/3.0/legalcode
-->
<mx:Application 
    xmlns:mx="http://www.adobe.com/2006/mxml"
    xmlns:gm="com.google.maps.*"
    backgroundGradientColors="[0xFFFFFF, 0xAAAAAA]"
    height="100%" width="100%" viewSourceURL="srcview/index.html">
    <mx:HBox>
        <mx:Label text="Search for Address:" fontWeight="bold" paddingTop="2" />
        <mx:TextInput id="addressText" width="250" keyDown="addressText_keyDown(event)" />
        <mx:Button id="go" label="Go" click="go_click()" />
    </mx:HBox>
    <gm:Map id="map"
        width="100%" 
        height="100%" 
        key="(Your API Key Here)"
        mapevent_mapready="map_mapReady(event)" />

    <mx:Script>
        <![CDATA[
            import com.google.maps.InfoWindowOptions;
            import com.google.maps.LatLng;    
            import com.google.maps.LatLngBounds;
            import com.google.maps.Map;    
            import com.google.maps.MapEvent;
            import com.google.maps.MapMouseEvent;
            import com.google.maps.MapType;

            import com.google.maps.controls.OverviewMapControl;
            import com.google.maps.controls.ScaleControl;
            import com.google.maps.controls.ZoomControl;
            import com.google.maps.controls.PositionControl;
            import com.google.maps.controls.MapTypeControl;

            import com.google.maps.overlays.MarkerOptions;
            import com.google.maps.overlays.Marker;

            import com.google.maps.services.Placemark;
            import com.google.maps.services.ClientGeocoderOptions;
            import com.google.maps.services.ClientGeocoder;
            import com.google.maps.services.GeocodingEvent;
                        
            import com.google.maps.styles.FillStyle;
            import com.google.maps.styles.StrokeStyle;
                        
            import com.ags.tools.PolygonOverlay;
            
            import mx.controls.Alert;
            
            // Parcels URL and parameters
            private var parcelsUrl:String = "http://sampleserver1.arcgisonline.com/" +
                "ArcGIS/rest/services/Portland/ESRI_LandBase_WebMercator/MapServer/1/query";
            
            private var polygonOverlay:PolygonOverlay;
            private var addressMarker:Marker;
            private var addressInfo:InfoWindowOptions;
            
            // Parcels symbols
            private var transparentFill:FillStyle;
            private var greyStroke:StrokeStyle;
            private var whiteStroke:StrokeStyle;
            
            private function map_mapReady(event:Event):void { 
                // Setup parcel symbols
                transparentFill = new FillStyle({ 
                    alpha: 0.0 });
                greyStroke = new StrokeStyle({
                    alpha: 1.0,
                    thickness: 1.5,
                    color: 0x333333 });
                whiteStroke = new StrokeStyle({
                    alpha: 1.0,
                    thickness: 1.5,
                    color: 0xffffff });
                
                // Add map controls
                var mtc:MapTypeControl = new MapTypeControl();
                map.addControl(mtc);
                var pc:PositionControl = new PositionControl();
                map.addControl(pc);
                var zc:ZoomControl = new ZoomControl();
                map.addControl(zc);
                var sc:ScaleControl = new ScaleControl();
                map.addControl(sc);
                var omc:OverviewMapControl = new OverviewMapControl();
                map.addControl(omc);
                
                polygonOverlay = new PolygonOverlay(map, parcelsUrl, 
                    17, 21, "RNO", transparentFill, greyStroke);
                
                // Add event listeners
                map.addEventListener(MapEvent.MAPTYPE_CHANGED, map_mapTypeChanged);

                // Initialize map            
                map.setCenter(new LatLng(45.520211, -122.65553), 17, 
                    MapType.NORMAL_MAP_TYPE);
            }
            
            private function map_mapTypeChanged(event:MapEvent):void {
                polygonOverlay.strokeStyle = 
                    (map.getCurrentMapType() == MapType.NORMAL_MAP_TYPE ? 
                    greyStroke : whiteStroke);
            }

            private function go_click():void {
                findAddress();
            }
            
            private function addressText_keyDown(event:KeyboardEvent):void {
                if (event.keyCode == 13) {
                    findAddress();
                } 
            }
            
            private function findAddress():void {
                trace("findAddress() - entered");
                var address:String = addressText.text;
                trace("findAddress() - address: " + address);

                // Constrain geocoder to a viewport that is in/around Portland, Oregon
                var sw:LatLng = new LatLng(-122.76728,45.45137);
                var ne:LatLng = new LatLng(-122.53211,45.59233);
                var viewport:LatLngBounds = new LatLngBounds(sw, ne);
                var options:ClientGeocoderOptions = new ClientGeocoderOptions();
                options.viewport = viewport;
                
                // Setup client geocoder and dispatch request
                var geocoder:ClientGeocoder = new ClientGeocoder();
                geocoder.setOptions(options);
                geocoder.addEventListener(GeocodingEvent.GEOCODING_SUCCESS, geocoder_GeocodingSuccess);
                geocoder.addEventListener(GeocodingEvent.GEOCODING_FAILURE, geocoder_GeocodingFailure);
                geocoder.geocode(address);
            }
            
            private function geocoder_GeocodingSuccess(event:GeocodingEvent):void {
                trace("geocoder_GeocodingSuccess() - entered");
                var placemarks:Array = event.response.placemarks;
                
                if (placemarks.length > 1) {
                    trace("geocoder_GeocodingSuccess() - multiple placemarks");
                    Alert.show("Multiple addresses found. Please try again.");
                } else if (placemarks.length == 0) {
                    trace("geocoder_GeocodingSuccess() - no placemarks");
                    Alert.show("Address not found. Please try again.");
                } else { // placemarks.length == 1
                    trace("geocoder_GeocodingSuccess() - single placemark");
                    var placemark:Placemark = placemarks[0];
                    var latLng:LatLng = placemark.point;
                    if (addressMarker != null) {
                        map.removeOverlay(addressMarker);
                        map.closeInfoWindow();
                    }
                                        
                    var options:MarkerOptions = new MarkerOptions();
                    options.fillStyle = new FillStyle({color:0x393fff});
                    options.strokeStyle = new StrokeStyle({color:0x000000});
                    addressMarker = new Marker(latLng, options);
                    
                    map.setCenter(latLng, 17);

                    addressMarker.addEventListener(MapMouseEvent.CLICK, address_click)
                    map.addOverlay(addressMarker);
                    
                    var addressDetails:Object = placemark.addressDetails;
                    var accuracy:Number = addressDetails.Accuracy;
                    addressInfo = new InfoWindowOptions();
                    addressInfo.content = placemark.address.replace(", ", "\n") + 
                        "\nAccuracy: " + translateAccuracyName(accuracy);
                    addressInfo.hasShadow = false;
                    addressInfo.pointOffset = new Point(0, -35);
                    addressMarker.openInfoWindow(addressInfo);
                } 
            }
            
            private function geocoder_GeocodingFailure(event:GeocodingEvent):void {
                trace("geocoder_GeocodingFailure() - entered");
                Alert.show("Address Geocoder Failed!");
            }
            
            private function address_click(event:MapMouseEvent):void {
                addressMarker.openInfoWindow(addressInfo);
            }
                        
            private function translateAccuracyName(accuracy:Number):String {
                switch (accuracy) {
                    case 0:
                        return "Unknown Location";
                    case 1:
                        return "Country";
                    case 2:
                        return "State";
                    case 3:
                        return "County";
                    case 4: 
                        return "City or Town";
                    case 5:
                        return "Zip Code";
                    case 6:
                        return "Street";
                    case 7:
                        return "Intersection";
                    case 8:
                        return "Address";
                    case 9:
                        return "Premises";
                }
                return "Unknown Accuracy Code: " + accuracy.toString();
            }

        ]]>
    </mx:Script>
</mx:Application>