= Sexy Map Application = == Overview == I'm [[http://www.personaltelco.net/static/node/|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 [[http://www.trans.ci.portland.or.us/bicycles/bikemap.pdf|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 * LinkFunction -> ReProActive 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 repeat 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} set selShape to "Elps" -- "Rctn" set selTop to y - dotRadius set selLeft to x - dotRadius set selBottom to y + dotRadius set selRight to x + dotRadius set antiAlias to true set featherAmt to 0.0 do javascript ("function makeEllipseSelection(selShape, selTop, selLeft, selBottom, selRight, antiAlias, featherAmt) { 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 ); } makeEllipseSelection( arguments[0] , arguments[1] , arguments[2] , arguments[3] , arguments[4] , arguments[5] , arguments[6] );") ¬ 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 end tell 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 & "\""" & return end repeat set text of document 1 to imageMapText end tell 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 end repeat if cellText is "" then exit repeat set end of myList to tuple set myRow to myRow + 1 end repeat Quit end tell 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 || ---- CategorySoftware