--- The Map module defines getAddressLocations and getAddresses import List import Maybe import System import URL import XML --- main = "done." --import GetOpt --import Map --main2 :: IO --main2 -- = let (flags, addresses, errors) = getOpt Permute options (unsafePerformIO $ --getArgs) -- in if length errors > 0 -- then error $ "Error: Invalid command line. " ++ usage -- else if elem Help flags -- then usage -- else unsafePerformIO $ getAddressesLocationsWikiCode addresses --- --data Flag = Help -- --options = [Option "h" ["help"] (NoArg Help) "Displays this help message."] -- --usage = usageInfo "Usage: map [OPTION...] address ..." options --- Represents locations. data Location = Location String -- longitude String -- latitude String -- label --- Accepts a location and returns its longitude. getLocationLongitude :: Location -> String getLocationLongitude (Location lon _ _) = lon --- Accepts a location and returns its latitude. getLocationLatitude :: Location -> String getLocationLatitude (Location _ lat _) = lat --- Accepts a location and returns its label. getLocationLabel :: Location -> String getLocationLabel (Location _ _ label) = label --- Accepts a list of addresses and returns a --- WikiCode command that displays a map plotting --- the addresses. getAddressesLocationsWikiCode :: [String] -> IO String getAddressesLocationsWikiCode addresses = getAddressesLocations addresses >>= return . locationsToWikiCode --- Accepts a list of addresses and returns the --- first location returned by Open Street Map for --- each address. getAddressesLocations :: [String] -> IO [Location] getAddressesLocations addresses = mapIO getAddressLocation addresses >>= return . catMaybes --- Accepts an address and returns the first --- location returned by Open Street Map. getAddressLocation :: String -> IO (Maybe Location) getAddressLocation address = do locations <- getAddressLocations address return $ if length locations == 0 then Nothing else Just $ head locations --- Accepts an address and returns the location of --- the address according to Open Street Map. getAddressLocations :: String -> IO [Location] getAddressLocations address = getContentsOfUrl ("http://nominatim.openstreetmap.org/search?format=xml&q=" ++ address) >>= return . parseXmlString >>= return . concatMap parseSearchResults --- Accepts a location and returns a WikiCode --- string that represents the location as a map --- point. locationToWikiCode :: Location -> String locationToWikiCode location = getLocationLatitude location ++ "," ++ getLocationLongitude location ++ "~" ++ getLocationLabel location --- Accepts a list of locations and returns a --- WikiCode command that maps the locations. locationsToWikiCode :: [Location] -> String locationsToWikiCode locations = "{{#isplay_map: " ++ (intercalate ";" $ map locationToWikiCode locations) ++ "}}" --- Accepts an XML Element that represents a Search --- Results element and returns the set of --- locations in the search results. parseSearchResults :: XmlExp -> [Location] parseSearchResults = map parsePlace . elemsOf --- Accepts an XML Place element and returns the --- location represented by the element. parsePlace :: XmlExp -> Location parsePlace element = let message = "[parsePlace] Error: An error occured while trying to parse a place element." in case element of XText _ -> error message XElem tagName attributes _ -> Location (fromMaybe (error $ message ++ " The 'lat' attribute is missing.") $ lookup "lat" attributes) (fromMaybe (error $ message ++ " The 'lon' attribute is missing.") $ lookup "lon" attributes) (fromMaybe (error $ message ++ " The 'display_name' attribute is missing.") $ lookup "display_name" attributes)