implementation module GoogleMaps
import HTML, StdEnv, JSON, GenUpdate, GenVisualize, GenVerify
derive JSONEncode TUIGoogleMap, TUIGoogleMapOptions, TUIGoogleStaticMap
derive JSONDecode MVCUpdate, ClickUpdate, ClickSource, ClickEvent, MarkerDragUpdate
derive gVisualizeText GoogleMapPosition, GoogleMapMarker, GoogleMapInfoWindow, GoogleMapType
derive gVisualizeHtml GoogleMapPosition, GoogleMapMarker, GoogleMapInfoWindow, GoogleMapType
derive gVisualizeEditor GoogleMapPosition, GoogleMapMarker, GoogleMapInfoWindow, GoogleMapType
derive gUpdate GoogleMapPosition, GoogleMapMarker, GoogleMapInfoWindow, GoogleMapType, GoogleStaticMap
derive gDefaultMask GoogleMapPosition, GoogleMapMarker, GoogleMapInfoWindow, GoogleMapType, GoogleStaticMap
derive gVerify GoogleMapPosition, GoogleMapMarker, GoogleMapInfoWindow, GoogleMapType, GoogleStaticMap
derive JSONEncode GoogleMap, GoogleMapMarker, GoogleMapInfoWindow, GoogleMapType, GoogleStaticMap
derive JSONDecode GoogleMap, GoogleMapMarker, GoogleMapInfoWindow, GoogleMapType, GoogleStaticMap
derive gEq GoogleMap, GoogleMapPosition, GoogleMapMarker, GoogleMapInfoWindow, GoogleMapType, GoogleStaticMap
JSONEncode{|GoogleMapPosition|} {lat,lng} = [JSONArray [JSONReal lat,JSONReal lng]]
JSONDecode{|GoogleMapPosition|} [JSONArray [JSONReal lat,JSONReal lng]:rest] = (Just {lat=lat,lng=lng},rest)
JSONDecode{|GoogleMapPosition|} [JSONArray [JSONInt lat,JSONReal lng]:rest] = (Just {lat=toReal lat,lng=lng},rest)
JSONDecode{|GoogleMapPosition|} [JSONArray [JSONReal lat,JSONInt lng]:rest] = (Just {lat=lat,lng=toReal lng},rest)
JSONDecode{|GoogleMapPosition|} [JSONArray [JSONInt lat,JSONInt lng]:rest] = (Just {lat=toReal lat,lng=toReal lng},rest)
JSONDecode{|GoogleMapPosition|} rest = (Nothing,rest)
derive bimap Maybe, (,)
:: MVCUpdate =
{ center :: !GoogleMapPosition
, zoom :: !Int
, type :: !GoogleMapType
}
:: ClickUpdate =
{ event :: !ClickEvent
, source :: !ClickSource
, point :: !GoogleMapPosition
}
:: ClickEvent = LEFTCLICK | RIGHTCLICK | DBLCLICK
:: ClickSource = MAP | MARKER GoogleMapPosition
:: MarkerDragUpdate =
{ index :: !Int
, point :: !GoogleMapPosition
}
:: TUIGoogleMap =
{ center :: GoogleMapPosition
, mapType :: GoogleMapType
, markers :: [GoogleMapMarker]
, xtype :: String
, taskId :: String
, name :: String
, editor :: Bool
, options :: TUIGoogleMapOptions
}
:: TUIGoogleMapOptions =
{ mapTypeControl :: Bool
, panControl :: Bool
, streetViewControl :: Bool
, zoomControl :: Bool
, scaleControl :: Bool
, scrollwheel :: Bool
, draggable :: Bool
, zoom :: Int
}
::TUIGoogleStaticMap =
{ width :: Int
, height :: Int
, xtype :: String
, url :: String
}
instance toString GoogleMapType
where
toString ROADMAP = "ROADMAP"
toString SATELLITE = "SATELLITE"
toString HYBRID = "HYBRID"
toString TERRAIN = "TERRAIN"
gVisualizeText{|GoogleMap|} _ _ = ["Map"]
gVisualizeHtml{|GoogleMap|} mode map = case mode of
AsLabel = [Text "Map"]
AsDisplay = [staticMap (convertToStaticMap map)]
gVisualizeEditor{|GoogleMap|} mbMap vst = visualizeCustom mkControl mbMap vst
where
mkControl name mbMap _ _ static vst=:{VSt|taskId}
| static
//TODO
= ([], vst)
//= ([htmlDisplay (staticMap (convertToStaticMap (fromMaybe defaultMap mbMap)))], vst)
| otherwise
= ([defaultDef (TUICustom ((mapPanel mbMap name True)))], vst)
where
mapPanel Nothing name ed = toJSON (tuidef defaultMap name ed)
mapPanel (Just map) name ed = toJSON (tuidef map name ed)
tuidef map name ed =
{ TUIGoogleMap
| center = map.GoogleMap.center
, mapType = map.GoogleMap.mapType
, markers = map.GoogleMap.markers
, xtype = "igooglemap"
, name = name
, taskId = fromMaybe "" taskId
, editor = ed
, options =
{ TUIGoogleMapOptions
| mapTypeControl = map.GoogleMap.mapTypeControl
, panControl = map.GoogleMap.panControl
, streetViewControl = map.GoogleMap.streetViewControl
, zoomControl = map.GoogleMap.zoomControl
, scaleControl = map.GoogleMap.scaleControl
, scrollwheel = map.GoogleMap.scrollwheel
, draggable = map.GoogleMap.draggable
, zoom = map.GoogleMap.zoom
}
}
gVisualizeText{|GoogleStaticMap|} mode (GoogleStaticMap _ _ u) = case mode of
AsLabel = ["Static Map"]
AsDisplay = ["Static Map: " +++ u]
gVisualizeHtml{|GoogleStaticMap|} mode map = case mode of
AsLabel = [Text "Static Map"]
AsDisplay = [staticMap map]
gVisualizeEditor{|GoogleStaticMap|} mbMap vst = visualizeCustom mkControl mbMap vst
where
mkControl _ mbMap _ _ _ vst = case mbMap of
Just (GoogleStaticMap w h u) = ([defaultDef (TUICustom (toJSON (staticMap w h u)))], vst)
_ = ([], vst)
staticMap w h u =
{ TUIGoogleStaticMap
| width = w
, height = h
, xtype = "igooglestaticmap"
, url = u
}
staticMap (GoogleStaticMap w h u) = ImgTag [SrcAttr u, WidthAttr (toString w), HeightAttr (toString h)]
gUpdate{|GoogleMap|} mode ust = basicUpdate mode parseUpdate defaultMap ust
where
parseUpdate json orig
# mbMVC = fromJSON json
| isJust mbMVC
# mvc = fromJust mbMVC
= {GoogleMap | orig & center = mvc.MVCUpdate.center, zoom = mvc.MVCUpdate.zoom, mapType = mvc.MVCUpdate.type}
# mbClick = fromJSON json
| isJust mbClick
# click = fromJust mbClick
# marker = {GoogleMapMarker | position = click.ClickUpdate.point, title = Nothing, infoWindow = Nothing, draggable = True}
= {GoogleMap | orig & markers = orig.GoogleMap.markers ++ [marker]}
# mbMarkerDrag = fromJSON json
| isJust mbMarkerDrag
# {MarkerDragUpdate|index,point} = fromJust mbMarkerDrag
= {GoogleMap | orig & markers = [if (i == index) {GoogleMapMarker|m & position = point} m \\ m <- orig.GoogleMap.markers & i <- [0..]]}
| otherwise = orig
gDefaultMask{|GoogleMap|} _ = [Touched []]
gVerify{|GoogleMap|} _ vst = alwaysValid vst //Maps are always valid
// -- Utility Functions --
defaultMap :: GoogleMap
defaultMap = { GoogleMap
| center = {GoogleMapPosition|lat = 51.82, lng = 5.86}
, mapTypeControl = True
, panControl = True
, streetViewControl = True
, zoomControl = True
, scaleControl = True
, scrollwheel = True
, draggable = True
, zoom = 10
, mapType = ROADMAP
, markers = []
}
minimalMap :: GoogleMap
minimalMap = { GoogleMap
| center = {GoogleMapPosition|lat = 51.82, lng = 5.86}
, mapTypeControl = False
, panControl = False
, streetViewControl = False
, zoomControl = False
, scaleControl = False
, scrollwheel = False
, draggable = False
, zoom = 10
, mapType = ROADMAP
, markers = []
}
convertToStaticMap :: !GoogleMap -> GoogleStaticMap
convertToStaticMap map =:{GoogleMap | center = {lat,lng}, zoom, mapType, markers}
# url = "http://maps.google.com/maps/api/staticmap?"
# cntr = "center="+++(toString lat)+++","+++(toString lng)
# zm = "zoom="+++(toString zoom)
# sz = "size=650x600"
# tp = "maptype="+++(toString mapType)
# mrkrs = "markers="+++(convertMarkers markers)
= GoogleStaticMap 650 600 (url+++cntr+++"&"+++zm+++"&"+++sz+++"&"+++tp+++"&"+++mrkrs+++"&sensor=false&key="+++GOOGLE_API_KEY)
where
convertMarkers :: [GoogleMapMarker] -> String
convertMarkers [] = "";
convertMarkers [x] = convertMarker x
convertMarkers [x:xs] = (convertMarker x)+++"|"+++(convertMarkers xs)
convertMarker :: GoogleMapMarker -> String
convertMarker mrkr =: {position ={lat,lng}, infoWindow}
= toString lat+++","+++toString lng