source: subversion/applications/routing/pyroute/projection.py @ 5850

Last change on this file since 5850 was 5850, checked in by ojw, 12 years ago

convert to an "integer zoom level" (so zooming isn't continuous, but must double or halve the detail in each step) -- this is to make the map images the same size as their original, so that cairo doesn't have to do any scaling

File size: 4.2 KB
Line 
1#!/usr/bin/python
2#-----------------------------------------------------------------------------
3# Projection code (lat/long to screen conversions)
4#
5# Usage:
6#   (library code for pyroute GUI, not for direct use)
7#-----------------------------------------------------------------------------
8# Copyright 2007, Oliver White
9#
10# This program is free software: you can redistribute it and/or modify
11# it under the terms of the GNU General Public License as published by
12# the Free Software Foundation, either version 3 of the License, or
13# (at your option) any later version.
14#
15# This program is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18# GNU General Public License for more details.
19#
20# You should have received a copy of the GNU General Public License
21# along with this program.  If not, see <http://www.gnu.org/licenses/>.
22#-----------------------------------------------------------------------------
23from tilenames import *
24
25class Projection:
26  def __init__(self):
27    self.xyValid = False
28    self.llValid = False
29    self.needsEdgeFind = False
30  def isValid(self):
31    return(self.xyValid and self.llValid)
32  def setView(self,x,y,w,h):
33    self.w = w
34    self.h = h
35    self.xc = x + self.w
36    self.yc = y + self.h
37    self.xyValid = True
38    if(self.needsEdgeFind):
39      self.findEdges()
40   
41  def recentre(self,lat,lon,zoom = None):
42    print "centering on %1.3f, %1.3f" % (lat,lon)
43    self.lat = lat
44    self.lon = lon
45    if(zoom != None):
46      self.implementNewZoom(zoom)
47    else:
48      self.findEdges()
49    self.llValid = True
50   
51  def setZoom(self, value, isAdjustment=False):
52    if(isAdjustment):
53      self.implementNewZoom(self.zoom + value)
54    else:
55      self.implementNewZoom(value)
56 
57  def limitZoom(self):
58    if(self.zoom < 6):
59      self.zoom = 6
60    if(self.zoom > 17):
61      self.zoom = 17
62     
63  def implementNewZoom(self, zoom):
64    self.zoom = int(zoom)
65    print "zoom set to %d" % zoom
66    self.limitZoom()
67    self.findEdges()
68 
69  def findEdges(self):
70    """(S,W,E,N) are derived from (lat,lon,scale)"""
71    if(not self.xyValid):
72      print "Can't find edges"
73      self.needsEdgeFind = True
74      return
75    self.px, self.py = latlon2xy(self.lat,self.lon,self.zoom)
76   
77    print "Centred on %1.1f,%1.1f" % (self.px,self.py)
78    unitSize = tileSizePixels()
79   
80    self.px1 = self.px - 0.5 * self.w / unitSize
81    self.px2 = self.px + 0.5 * self.w / unitSize
82    self.py1 = self.py - 0.5 * self.h / unitSize
83    self.py2 = self.py + 0.5 * self.h / unitSize
84   
85    self.pdx = self.px2 - self.px1
86    self.pdy = self.py2 - self.py1
87   
88    print "Viewing %1.1f - %1.1f, %1.1f - %1.1f" % \
89      (self.px1,
90      self.px2,
91      self.py1,
92      self.py2);
93   
94    self.N,self.W = xy2latlon(self.px1, self.py1, self.zoom)
95    self.S,self.E = xy2latlon(self.px2, self.py2, self.zoom)
96   
97    print "Lat %1.1f - %1.1f, Lon %1.1f - %1.1f" % \
98      (self.S,
99      self.N,
100      self.W,
101      self.E)
102     
103    self.needsEdgeFind = False
104 
105  def pxpy2xy(self,px,py):
106    x = self.w * (px - self.px1) / self.pdx
107    y = self.h * (py - self.py1) / self.pdy
108    return(x,y)
109 
110  def nudge(self,dx,dy):
111    unitSize = tileSizePixels()
112    newXC = self.px - dx / unitSize
113    newYC = self.py - dy / unitSize
114   
115    if(1):
116      self.lat,self.lon = xy2latlon(newXC,newYC, self.zoom)
117    else:
118      self.lat,self.lon = self.xy2ll(newXC,newYC) 
119    self.findEdges()
120
121  def ll2xy(self,lat,lon):
122    px,py = latlon2xy(lat,lon,self.zoom)
123    #print "%1.3f,%1.3f -> %1.1f,%1.1f" % (lat,lon,px,py)
124    unitSize = tileSizePixels()
125    x = (px - self.px1) * unitSize
126    y = (py - self.py1) * unitSize
127    return(x,y)
128 
129  def xy2ll(self,x,y):
130    unitSize = tileSizePixels()
131    px = self.px1 + x / unitSize
132    py = self.py1 + y / unitSize
133    lat,lon = xy2latlon(px, py, self.zoom)
134    return(lat,lon)
135 
136  def onscreen(self,x,y):
137    return(x >= 0 and x < self.w and y >= 0 and y < self.h)
138 
139  def relXY(self,x,y):
140    return(x/self.w, y/self.h)
141   
Note: See TracBrowser for help on using the repository browser.