Sexy Map Application
Overview
I'm playing with map making to visually explain PersonalTelco's coverage around PortlandOregon. I'm mostly interested in making the map look sexy. I'm using the City of Portland Office of Transportation Bike Map as a starting point. I grabbed a few tools on my AppleMacintosh that are simple to play with by hand and then started automating parts. I'm using AppleScript because it's been a while and I am curious where it's at these days. --DarrinEden
To Do
ScaleCaching -> Vector
ThreeDimension -> Tiles
The code for a zoomed in map is incomplete and fubared at best. I'm still fixing the zoom map by hand.
Code
property dotRadius : 10 property resultWidth : 450
global myList
global cropNWx global cropNWy global cropSEx global cropSEy
global scaleX global scaleY
global myPage
global pdxSpotList global pdxMapOriginal
tell application "Finder" to set homePath to (home as string)
set pdxSpotList to (homePath & "Desktop:spots.xls") set pdxMapOriginal to (homePath & "Desktop:bikemap.pdf" as alias)
on main()
- loadList() -- Build the entire map setEntireMap() drawMap() linkMap() -- Build the downtown map setDowntownMap() drawMap() linkMap()
end main
-- Prepare data for building entire map of Portland on setEntireMap()
- set cropNWx to 19 set cropNWy to 248 set cropSEx to 1124 set cropSEy to 1247 set scaleX to 1105 set scaleY to 999 set myPage to 1
end setEntireMap
-- Prepare data for building downtown Portland on setDowntownMap()
- set cropNWx to 43 set cropNWy to 31 set cropSEx to 615 set cropSEy to 552 set scaleX to 1105 set scaleY to 999 set myPage to 2 repeat with z in myList
- set item 2 of z to (item 2 of z) - 294 set item 3 of z to (item 3 of z) - 355
end setDowntownMap
-- Use Photoshop to draw on a PDF version of the biking routes of Portland on drawMap()
- tell application "Adobe Photoshop CS"
- activate open pdxMapOriginal as PDF with options {class:PDF open options, page:myPage} set maxX to 0 set maxY to 0 set minX to 1500 set minY to 1500 repeat with z in myList
- set spotName to item 1 of z set x to item 2 of z set y to item 3 of z if x is greater than maxX then set maxX to (x + dotRadius) if y is greater than maxY then set maxY to (y + dotRadius) if minX is greater than x then set minX to (x - dotRadius) if minY is greater than y then set minY to (y - dotRadius) make new art layer at beginning of current document ¬
- with properties {name:spotName, blend mode:normal}
var selectionChannel = new ActionReference();
- selectionChannel.putProperty( charIDToTypeID( \"Chnl\" ), charIDToTypeID( \"fsel\" ) );
var makeSelection = new ActionDescriptor();
- makeSelection.putReference( charIDToTypeID( \"null\" ), selectionChannel );
var selectionParameters = new ActionDescriptor();
- selectionParameters.putUnitDouble( charIDToTypeID( \"Top \" ), charIDToTypeID( \"#Pxl\" ), selTop ); selectionParameters.putUnitDouble( charIDToTypeID( \"Left\" ), charIDToTypeID( \"#Pxl\" ), selLeft ); selectionParameters.putUnitDouble( charIDToTypeID( \"Btom\" ), charIDToTypeID( \"#Pxl\" ), selBottom ); selectionParameters.putUnitDouble( charIDToTypeID( \"Rght\" ), charIDToTypeID( \"#Pxl\" ), selRight ); makeSelection.putObject( charIDToTypeID( \"T \" ), charIDToTypeID( selShape ), selectionParameters ); makeSelection.putUnitDouble( charIDToTypeID( \"Fthr\" ), charIDToTypeID( \"#Pxl\" ), featherAmt ); makeSelection.putBoolean( charIDToTypeID( \"AntA\" ), antiAlias );
executeAction( charIDToTypeID( \"setd\" ), makeSelection, DialogModes.NO );
- set spotName to item 1 of z set x to item 2 of z set y to item 3 of z if x is greater than maxX then set maxX to (x + dotRadius) if y is greater than maxY then set maxY to (y + dotRadius) if minX is greater than x then set minX to (x - dotRadius) if minY is greater than y then set minY to (y - dotRadius) make new art layer at beginning of current document ¬
- with arguments {selShape, selTop, selLeft, selBottom, selRight, antiAlias, featherAmt}
- fill selection of current document with contents ¬
- {class:RGB color, red:81, green:172, blue:205} blend mode ¬ vivid light opacity 90 without preserving transparency
- end repeat
-- display dialog "minX: " & minX & " miny: " & minY & " maxX: " & maxX & " maxY: " & maxY crop current document bounds {cropNWx, cropNWy, cropSEx, cropSEy} -- resize image current document width resultWidth -- save current document in resultGraphic as PNG with copying
- activate open pdxMapOriginal as PDF with options {class:PDF open options, page:myPage} set maxX to 0 set maxY to 0 set minX to 1500 set minY to 1500 repeat with z in myList
end drawMap
-- Write down all the imagemap data for a clickable map on a web page on linkMap()
tell application "TextEdit"
- set imageMapText to "" repeat with z in myList
- set spotName to item 1 of z set x to item 2 of z set y to item 3 of z set x to round ((x - cropNWx) * (resultWidth / scaleX)) set y to round ((y - cropNWy) * ((resultWidth / scaleX) * scaleY) / scaleY) set x to x - 2 set y to y - 3
set AppleScript's text item delimiters to " " set stringParts to text items of spotName set AppleScript's text item delimiters to "" set spotName to stringParts as text
set imageMapText to imageMapText & "<area shape=\"circle\" alt=\"" & spotName & "\" coords=\"" & x & "," & y & "," & (round ((dotRadius + 1) / 2)) & "\" href=\"#" & spotName & "\">" & return
- set spotName to item 1 of z set x to item 2 of z set y to item 3 of z set x to round ((x - cropNWx) * (resultWidth / scaleX)) set y to round ((y - cropNWy) * ((resultWidth / scaleX) * scaleY) / scaleY) set x to x - 2 set y to y - 3
- set imageMapText to "" repeat with z in myList
end linkMap
-- Load data for spots from a spreadsheet on loadList()
- tell application "Microsoft Excel"
- Open pdxSpotList set myRow to 1 set myList to {} repeat
- set tuple to {} repeat with myColumn from 1 to 3
set currentCell to "R" & myRow & "C" & myColumn as string set cellText to text of Cell currentCell if cellText is "" then exit repeat set end of tuple to cellText
- set tuple to {} repeat with myColumn from 1 to 3
- Open pdxSpotList set myRow to 1 set myList to {} repeat
end loadList
main()
Data
Pioneer Courthouse Square Area |
514 |
737 |
Powells Bookstore |
499 |
715 |
Stumptown Café Ash |
536 |
722 |
Anna Bannanas |
439 |
653 |
World Cup Coffee and Tea |
465 |
693 |
Ecotrust |
502 |
678 |
Coffee Plant |
513 |
733 |
Backspace |
525 |
713 |
South Park Blocks |
486 |
781 |
Moonlight Staffing at PGE Park |
452 |
736 |
Couch Park |
452 |
690 |
The Basement Public House |
635 |
776 |
Red Wing Coffee and Baking |
604 |
804 |
Rose and Raindrop |
637 |
745 |
Subway Sandwich Restaurant |
756 |
800 |
Hawthorne Hosteling International |
735 |
800 |
Costellos Travel Caffe |
690 |
639 |
Hollywood Library |
792 |
628 |
Arbor Lodge Park |
441 |
402 |
Irving Park |
689 |
550 |
Ugly Mug Coffeehouse |
622 |
1125 |
The Crow Bar |
534 |
526 |
Cafe La Dolce Vita |
645 |
472 |
Urban Grind Coffeehouse |
701 |
684 |
Cedar Hills Crossing Shopping Center |
29 |
956 |
Portland Independent Media Center |
752 |
769 |
Northstar Coffeehouse |
508 |
356 |
Goldrush Coffee Bar |
602 |
592 |
WSMF |
722 |
760 |
Rocky Butte |
1062 |
597 |
Bar 71 |
545 |
723 |
Daily Double |
450 |
718 |
Vivace Coffee House |
420 |
647 |
Dittos |
582 |
541 |
Urban Grind In The Pearl |
482 |
672 |
Crema Bakery and Cafe |
722 |
735 |
Stumptown Café Belmont |
748 |
771 |
Stumptown Café Division |
817 |
847 |
Caffe Uno |
798 |
626 |
Old Town Pizza |
542 |
708 |
Powells Technical Bookstore |
514 |
715 |
City Club of Portland/O'Bryant Square |
513 |
721 |
Muddy's Coffeehouse |
534 |
544 |
The Fresh Pot |
530 |
512 |
Nocturnal |
667 |
724 |
The Black Rooster Cafe |
503 |
726 |
Staccato Gelato |
718 |
713 |
Wax Cafe |
502 |
461 |
Westover Towers |
390 |
669 |
Foxfire Teas |
825 |
549 |
Humboldt |
590 |
498 |
Veganopolis |
531 |
732 |
Bar XV |
546 |
720 |