Changeset 501
- Timestamp:
- 02/26/08 21:33:54 (9 months ago)
- Files:
-
- trunk/py/wscompose/convexhull.py (added)
- trunk/py/wscompose/markers.py (modified) (3 diffs)
- trunk/py/wscompose/pinwin.py (modified) (6 diffs)
- trunk/py/wscompose/validate.py (modified) (2 diffs)
- trunk/py/wscompose/__init__.py (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/py/wscompose/markers.py
r476 r501 442 442 # ########################################################## 443 443 444 def mk_perspective_shadow (self ) :444 def mk_perspective_shadow (self, img, corners) : 445 445 446 446 # … … 455 455 # im.transform(size, PERSPECTIVE, data) 456 456 # 457 458 pass 459 457 458 """ 459 460 Returns a new surface containing the image reshaped to fit inside the quadrilateral defined by the given vertices (top-left, top-right, bottom-right, bottom-left). 461 462 For the sake of my sanity, we're assuming that the left and right sides, post-transform, will be straight vertical lines. If you intend them to be otherwise, I shall punch you in the cock. Also assumed is that the smaller end doesn't extend above or below the longer end (though I'm not sure that it doing so would actually be a problem). 463 """ 464 465 tl, tr, br, bl = corners 466 sourceSize = img.size 467 newSize = (max(tr[0], br[0]), max(bl[1], br[1])) 468 469 a = float(sourceSize[0] * (br[1] - tr[1])) / \ 470 (newSize[0] * (bl[1] - tl[1])) 471 b = 0 472 c = 0 473 d = float(sourceSize[1] * (tl[1] - tr[1])) / \ 474 (newSize[0] * (bl[1] - tl[1])) 475 e = float(sourceSize[1]) / \ 476 (bl[1] - tl[1]) 477 f = float(-(sourceSize[1] * tl[1])) / \ 478 (bl[1] - tl[1]) 479 g = float(tl[1] - tr[1] + br[1] - bl[1]) / \ 480 (newSize[0] * (bl[1] - tl[1])) 481 h = 0 482 vals = [a, b, c, d, e, f, g, h] 483 484 return img.transform (newSize, Image.PERSPECTIVE, vals, Image.BILINEAR) 485 486 460 487 # ########################################################## 461 488 … … 566 593 567 594 pw = pinwin(w, h, 15) 568 im = pw. draw()569 570 im.save("/home/asc/Desktop/mrk.png")595 im = pw.mk_pinwin() 596 im = pw.mk_perspective_shadow(im, ((10,100), (10,10), (500,500), (500,200))) 597 # im.save("/home/asc/Desktop/mrk.png") 571 598 im.show() trunk/py/wscompose/pinwin.py
r478 r501 9 9 10 10 import wscompose 11 import convexhull 11 12 12 13 import wscompose.plotting … … 36 37 37 38 # 39 40 if self.ctx.has_key('polylines') : 41 img = self.draw_polylines(img) 42 43 # 44 45 if self.ctx.has_key('hulls') : 46 img = self.draw_convex_hulls(img) 47 48 # 38 49 39 50 if self.ctx.has_key('dots') : … … 95 106 # ########################################################## 96 107 97 # only works for method='bbox' ... WTF? 98 108 def draw_polylines (self, img) : 109 110 for poly in self.ctx['polylines'] : 111 img = self.draw_polyline(img, poly) 112 113 return img 114 115 # ########################################################## 116 117 def draw_polyline (self, img, poly) : 118 119 dr = ImageDraw.Draw(img) 120 cnt = len(poly) 121 i = 0 122 123 grey = (42, 42, 42) 124 125 while i < cnt : 126 127 j = i + 1 128 129 if j == cnt : 130 break 131 132 cur = self.latlon_to_point(poly[i]['latitude'], poly[i]['longitude']) 133 next = self.latlon_to_point(poly[j]['latitude'], poly[j]['longitude']) 134 135 dr.line((cur.x, cur.y, next.x, next.y), fill=grey, width=4) 136 i += 1 137 138 # 139 140 return img 141 142 # ########################################################## 143 144 def draw_convex_hulls(self, img) : 145 146 dr = ImageDraw.Draw(img) 147 148 for type in self.ctx['hulls'] : 149 150 points = [] 151 152 for coord in self.ctx[type] : 153 154 pt = self.latlon_to_point(coord['latitude'], coord['longitude']) 155 points.append((pt.x, pt.y)) 156 157 hull = convexhull.convexHull(points) 158 159 # 160 # no way to assign width to polygon outlines in PIL... 161 # 162 163 pink = (255, 0, 132) 164 cnt = len(hull) 165 i = 0 166 167 while i < cnt : 168 169 (x1, y1) = hull[i] 170 171 j = i + 1 172 173 if j == cnt : 174 (x2, y2) = hull[0] 175 else : 176 (x2, y2) = hull[j] 177 178 dr.line((x1, y1, x2, y2), fill=pink, width=6) 179 i += 1 180 181 return img 182 183 # ########################################################## 184 99 185 # To do : move this code in to methods that can be run 100 186 # easily from unit tests and/or CLI tools... … … 390 476 self.error(141, e) 391 477 return False 478 479 # 480 # polylines 481 # 482 483 if params.has_key('polyline') : 484 485 try : 486 valid['polylines'] = validator.polylines(params['polyline']) 487 except Exception, e : 488 self.error(142, e) 489 return False 490 491 # 492 # 493 # 494 495 if params.has_key('convex') : 496 497 try : 498 valid['hulls'] = validator.convex(params['convex']) 499 except Exception, e : 500 self.error(143, e) 501 return False 502 503 # 504 # Happy happy 505 # 392 506 393 507 return valid … … 410 524 wscompose.handler.help_parameters(self) 411 525 526 self.help_option('dot', 'Draw a pinwin-style dot (but not the marker) at a given point. You may pass multiple dot arguments, each of which should contain the following comma separated values :', False) 527 self.help_option('label', 'A unique string to identify the dot by', True, 1) 528 self.help_option('point', 'A comma-separated string containing the latitude and longitude indicating the point where the dot should be placed', True, 1) 529 self.help_option('radius', 'The radius, in pixels, of the dot - the default is 18', False, 1) 530 412 531 self.help_option('marker', 'Draw a pinwin-style marker at a given point. You may pass multiple marker arguments, each of which should contain the following comma separated values :', False) 413 532 self.help_option('label', 'A unique string to identify the marker by', True, 1) … … 415 534 self.help_option('dimensions', 'A comma-separated string containing the height and width of the marker canvas - the default is 75 x 75', False, 1) 416 535 417 self.help_option('dot', 'Draw a pinwin-style dot (but not the marker) at a given point. You may pass multiple dot arguments, each of which should contain the following comma separated values :', False) 418 self.help_option('label', 'A unique string to identify the dot by', True, 1) 419 self.help_option('point', 'A comma-separated string containing the latitude and longitude indicating the point where the dot should be placed', True, 1) 420 self.help_option('radius', 'The radius, in pixels, of the dot - the default is 18', False, 1) 421 422 self.help_option('plot', 'Plot -- but do not render -- the x and y coordinates for a given point. Coordinate data will be returned HTTP header(s) named \'X-wscompose-plot-\' followed by the label you choose when passing latitude and longitude information. You may pass multiple plot arguments, each of which should contain the following comma separated values :', False) 423 self.help_option('label', 'A unique string to identify the plotting by', True, 1) 424 self.help_option('point', 'A comma-separated string containing the latitude and longitude indicating the point to be plotted', True, 1) 425 536 self.help_option('polyline', 'Draw a polyline on the map. Polylines are passed as multiple coordinates (comma-separated latitude and longitude pairs) each separated by a single space. You may pass multiple \'polyline\' arguments. This option is currently experimental and arguments may change.', False) 537 538 self.help_option('convex', 'Draw a polyline representing the convex hull of a collection of points passed in the \'marker\', \'dot\' or \'plot\' arguments (see above). Valid options are, not surprisingly : \'marker\', \'dot\' or \'plot\'; you may pass multiple \'convex\' arguments. This option is currently experimental and arguments may change.', False) 539 426 540 self.help_option('fill', 'A helper argument which if present will cause each marker specified to be filled with the contents of map for the marker\'s coordinates at zoom level 15. The value should be a valid ModestMaps map tile provider.', False) 427 541 trunk/py/wscompose/validate.py
r482 r501 21 21 'num' : re.compile(r"^\d+$"), 22 22 'provider' : re.compile(r"^([A-Z_]+)$"), 23 'label' : re.compile(r"^(?:[a-z0-9-_]+)$") 23 'label' : re.compile(r"^(?:[a-z0-9-_]+)$"), 24 'hull' : re.compile(r"^(marker|dot|plot)$") 24 25 } 25 26 … … 312 313 313 314 # ########################################################## 315 316 def polylines (self, lines) : 317 318 valid = [] 319 320 for poly in lines : 321 322 points = [] 323 324 for pt in poly.split(" ") : 325 326 coord = pt.split(",") 327 328 if len(coord) != 2 : 329 raise Exception, "Polyline coordinate missing data" 330 331 (lat, lon) = map(string.strip, coord) 332 333 lat = self.latlon(lat) 334 lon = self.latlon(lon) 335 336 points.append({'latitude':lat, 'longitude':lon}) 337 338 valid.append(points) 339 340 return valid 341 342 # ########################################################## 343 344 def convex (self, hulls) : 345 346 valid = [] 347 348 for label in hulls : 349 350 if not self.regexp('hull', label) : 351 raise Exception, "Unknown marker type for convex hulls" 352 353 valid.append(label) 354 355 return valid 356 357 # ########################################################## 314 358 315 359 def __num (self, input) : trunk/py/wscompose/__init__.py
r480 r501 241 241 self.send_header("X-wscompose-Map-Zoom", self.ctx['zoom']) 242 242 243 if self.ctx.has_key('plot ') :244 for data in self.ctx['plot '] :243 if self.ctx.has_key('plots') : 244 for data in self.ctx['plots'] : 245 245 246 246 pt = self.latlon_to_point(data['latitude'], data['longitude']) … … 380 380 return False 381 381 382 # you can blame migurski for this 383 384 if params.has_key('zoom') : 385 self.error(125, "'zoom' is not a valid argument when method is 'extent'") 386 return False 387 382 388 elif params['method'][0] == 'bbox' : 383 389 … … 406 412 except Exception, e : 407 413 self.error(124, e) 414 return False 415 416 # you can blame migurski for this 417 418 for p in ('height', 'width') : 419 if params.has_key(p) : 420 self.error(125, "'%s' is not a valid argument when method is 'bbox'" % p) 408 421 return False 409 422 … … 448 461 449 462 try : 450 valid['plot '] = validator.plots(params['plot'])463 valid['plots'] = validator.plots(params['plot']) 451 464 except Exception, e : 452 465 self.error(141, e) … … 540 553 X-wscompose-plot-roy: 667,285""") 541 554 542 self.help_para("Most headers are self-explanatory. Markers, dots and plottingcoordinates are a little more complicated.")543 544 self.help_para("The string after 'X-wscompose-plot -' is the label assigned to the marker when the API call was made. The value is a comma separated list containing the x and y coordinates for (label's) corresponding latitude and longitude.")555 self.help_para("Most headers are self-explanatory. Plotted coordinates are a little more complicated.") 556 557 self.help_para("The string after 'X-wscompose-plot' is the label assigned to the marker when the API call was made. The value is a comma separated list containing the x and y coordinates for (label's) corresponding latitude and longitude.") 545 558 546 559 # ##########################################################
