[GRASS-SVN] r39213 - grass/branches/develbranch_6/gui/tcltk/gis.m
svn_grass at osgeo.org
svn_grass at osgeo.org
Tue Sep 15 01:12:08 EDT 2009
Author: cmbarton
Date: 2009-09-15 01:12:06 -0400 (Tue, 15 Sep 2009)
New Revision: 39213
Modified:
grass/branches/develbranch_6/gui/tcltk/gis.m/mapcanvas.tcl
Log:
Fixed bug that prevented zooming latlon regions at global scales.
Modified: grass/branches/develbranch_6/gui/tcltk/gis.m/mapcanvas.tcl
===================================================================
--- grass/branches/develbranch_6/gui/tcltk/gis.m/mapcanvas.tcl 2009-09-15 05:03:04 UTC (rev 39212)
+++ grass/branches/develbranch_6/gui/tcltk/gis.m/mapcanvas.tcl 2009-09-15 05:12:06 UTC (rev 39213)
@@ -115,6 +115,7 @@
# proj_is_ll is 1 for a Lat/Lon projection, 0 otherwise
global proj_is_ll
+
# DMS format: 0 is ddd.dddddd, 1 is ddd:mm.mmmm', 2 is ddd:mm'ss.sss"
global dms_format
@@ -174,13 +175,9 @@
# run get_mapunits to check projection
MapCanvas::get_mapunits
- if { $proj_is_ll } {
- # Explore mode is off by default (can't peer past 90deg)
- set exploremode($mon) 0
- } else {
- # Explore mode is on by default
- set exploremode($mon) 1
- }
+
+ # exploremode set initially (map fills display canvas)
+ set exploremode($mon) 1
# FIXME: make this settable from the UI or use GRASS_DMS_FORMAT enviro var
# DMS format: 0 is ddd.dddddd, 1 is ddd:mm.mmmm', 2 is ddd:mm'ss.sss"
@@ -398,14 +395,46 @@
# Sense - 0 means largest no larger, 1 means smallest no smaller
# We will change rectangle 1
proc MapCanvas::shrinkwrap {sense nsew1 ar2 } {
+ global proj_is_ll
+
foreach {n1 s1 e1 w1} $nsew1 {break}
+ # Limit extents for latlon regions
+ if {$proj_is_ll && $sense} {
+ if {$n1 > 90} {set n1 90}
+ if {$s1 > 90} {set s1 90}
+ if {$n1 < -90} {set n1 -90}
+ if {$s1 < -90} {set s1 -90}
+
+ while {$e1 > 360} {set e1 [expr $e1 - 360]}
+ while {$e1 < -360} {set e1 [expr $e1 + 360]}
+ while {$w1 > 360} {set w1 [expr $w1 - 360]}
+ while {$w1 < -360} {set w1 [expr $w1 + 360]}
+
+ if {$w1 > 180 && $w1 <= 360} {set w1 [expr {$w1 - 360}]}
+ if {$w1 < -180 && $w1 >= -360} {set w1 [expr {$w1 + 360}]}
+ if {$e1 > 180 && $e1 <= 360} {set e1 [expr {$e1 - 360}]}
+ if {$e1 < -180 && $e1 >= -360} {set e1 [expr {$e1 + 360}]}
+ }
+
set ns1 [expr {$n1 - $s1}]
set ew1 [expr {$e1 - $w1}]
+ # reset for latlon location
+ if {$proj_is_ll && $sense} {
+ if {$ns1 < 0} {set ns1 [expr abs($ns1)]}
+ if {$ns1 > 180} {set ns1 180}
+ if {$ew1 < 0} {set ew1 [expr 360 - abs($ew1)]}
+ if {$ew1 > 360} {set ew1 360}
+ }
+
# Width / height
# Big aspect ratio is wide, small aspect ratio is tall
- set ar1 [expr { 1.0 * $ew1 / $ns1 }]
+ if {$ns1 != 0} {
+ set ar1 [expr { 1.0 * $ew1 / $ns1 }]
+ } else {
+ return
+ }
# If rectangle one is wider than rectangle 2.
# (or rectangle one isn't wider rectangle box 2 and the sense is inverted)
@@ -424,12 +453,14 @@
set re1 $e1
set rw1 $w1
set goal [expr {$ew1 / $ar2}]
+
+ # set limit for latlon location
set midpoint [expr {$s1 + $ns1 / 2}]
set rn1 [expr {$midpoint + $goal / 2}]
set rs1 [expr {$midpoint - $goal / 2}]
}
- set result [list $rn1 $rs1 $re1 $rw1]
+ set result [list $rn1 $rs1 $re1 $rw1]
return $result
}
@@ -437,6 +468,9 @@
proc MapCanvas::get_mapunits {} {
global proj_is_ll
+
+ set proj_is_ll 0
+
# get map units from PROJ_UNITS
if {![catch {open "|g.proj -p" r} input]} {
set key ""
@@ -444,7 +478,6 @@
while {[gets $input line] >= 0} {
if { [string equal "XY location (unprojected)" "$line"] } {
set mapunits "map units"
- set proj_is_ll 0
break
}
regexp -nocase {^(.*):(.*)$} $line trash key value
@@ -452,7 +485,11 @@
set value [string trim $value]
set prj($key) $value
}
- if {[catch {close $input} error]} {
+
+ # Set for latlon locations
+ if { $prj(proj) == "ll"} {set proj_is_ll 1}
+
+ if {[catch {close $input} error]} {
GmLib::errmsg $error [G_msg "g.proj or projection error"]
return
}
@@ -462,12 +499,6 @@
# May already be set above if locn was XY.
if { ! [ info exist mapunits ] } {
set mapunits $prj(units)
-
- if { [string eq "Lat/Lon" "$prj(name)"] } {
- set proj_is_ll 1
- } else {
- set proj_is_ll 0
- }
}
return $mapunits
@@ -565,7 +596,7 @@
set driver_h($mon) [expr {round ($y2 - $y1)}]
set driver_w($mon) [expr {round ($x2 - $x1)}]
}
-
+
#set display environment
set env(GRASS_WIDTH) "$driver_w($mon)"
set env(GRASS_HEIGHT) "$driver_h($mon)"
@@ -587,8 +618,8 @@
variable opclist
variable mapframe
variable zoom_attrs
+ variable exploremode
global proj_is_ll
- variable exploremode
global env
global drawprog
global devnull
@@ -607,30 +638,14 @@
set values [MapCanvas::currentzoom $mon]
set options {}
foreach attr $zoom_attrs value $values {
- if {$attr != "rows" && $attr != "cols"} {
- if { $proj_is_ll } {
- if {$attr == "n" && $value > 90} {
- set value 90
- if {$exploremode($mon)} {
- tk_messageBox -type ok -icon warning -parent .mapcan($mon) \
- -message [G_msg "Cannot explore beyond the poles: switching into constrained mode"] \
- -title [G_msg "Switching to constrained mode"]
- MapCanvas::exploremode $mon 0
- }
- }
- if {$attr == "s" && $value < -90} {
- set value -90
- if {$exploremode($mon)} {
- tk_messageBox -type ok -icon warning -parent .mapcan($mon) \
- -message [G_msg "Cannot explore beyond the poles: switching into constrained mode"] \
- -title [G_msg "Switching to constrained mode"]
- MapCanvas::exploremode $mon 0
- }
- }
- }
- lappend options "$attr=$value"
- }
- }
+ if { $proj_is_ll} {
+ if {$attr == "n" && $value > 90} {set value 90}
+ if {$attr == "n" && $value < -90} {set value -90}
+ if {$attr == "s" && $value > 90} {set value 90}
+ if {$attr == "s" && $value < -90} {set value -90}
+ }
+ if {$attr != "rows" && $attr != "cols"} {lappend options "$attr=$value"}
+ }
# Now use the region values to get the region printed back out in -p format
# including lat long now as dd:mm:ss
@@ -642,7 +657,7 @@
}
}
if {[catch {close $input} error]} {
- GmLib::errmsg $error [G_msg "Error setting region"]
+ GmLib::errmsg $error [G_msg "Error setting region 1"]
return
}
# Finally put this into wind file format to use with GRASS_REGION
@@ -652,14 +667,12 @@
}
set MapCanvas::msg($mon) [G_msg "please wait..."]
- $mapframe($mon) showstatusbar progression
+ $mapframe($mon) showstatusbar progression
incr drawprog
# only use dynamic region for display geometry; use WIND for computational geometry
set env(GRASS_REGION) $gregion
-
-
# Setting the font really only needs to be done once per display start
incr drawprog
GmGroup::display "root" $mod
@@ -945,10 +958,12 @@
# Pass second argument true to switch in, false to switch out
proc MapCanvas::exploremode { mon boolean } {
variable exploremode
+ variable can
# Set the explore mode to yes or no (the input)
set exploremode($mon) $boolean
+ $can($mon) delete map$mon
# Request a redraw with a geometry change (not just a zoom change).
# Flag it at as such (2)
MapCanvas::request_redraw $mon 2
@@ -1017,18 +1032,8 @@
global screenpct pctentry pixelentry geoentry geogentry llvert llhoriz
set b1east [MapCanvas::scrx2mape $mon %x]
set b1north [MapCanvas::scry2mapn $mon %y]
- if { $proj_is_ll } {
- if { $b1north < -90 } {
- set coords($mon) "$b1east -90"
- } elseif { $b1north > 90 } {
- set coords($mon) "$b1east 90"
- } else {
- set coords($mon) "$b1east $b1north"
- }
- } else {
- set coords($mon) "$b1east $b1north"
- }
-
+ set coords($mon) "$b1east $b1north"
+
# grab coordinates at mouse click for georectification
if { [info exists geoentry] } {
$geoentry insert 0 $b1coords
@@ -1106,29 +1111,29 @@
switch $dms_format {
0 {
- set res_str [format "%.6g" $res]
+ set res_str [format "%.6g" $res]
}
1 {
- if { $min_f == 0 } {
- set res_str [format "%.0f\xB0" $deg_d ]
- } else {
- set res_str [format "%.0f\xB0%02.4g'" $deg_d $min_f ]
- }
+ if { $min_f == 0 } {
+ set res_str [format "%.0f\xB0" $deg_d ]
+ } else {
+ set res_str [format "%.0f\xB0%02.4g'" $deg_d $min_f ]
+ }
}
2 {
# 'g.region -g' doesn't report enough sig digs for LL so we get rounding errors!
- if { [expr abs($sec_f - 60)] < 0.0001 } {
- set min_d [expr $min_d + 1]
- set sec_f "0"
- }
+ if { [expr abs($sec_f - 60)] < 0.0001 } {
+ set min_d [expr $min_d + 1]
+ set sec_f "0"
+ }
- if { $sec_f != 0 } {
- set res_str [format "%.0f\xB0%02.0f'%02.3g\"" $deg_d $min_d $sec_f ]
- } elseif { $min_d != 0 } {
- set res_str [format "%.0f\xB0%02.0f'" $deg_d $min_d ]
- } else {
- set res_str [format "%.0f\xB0" $deg_d ]
- }
+ if { $sec_f != 0 } {
+ set res_str [format "%.0f\xB0%02.0f'%02.3g\"" $deg_d $min_d $sec_f ]
+ } elseif { $min_d != 0 } {
+ set res_str [format "%.0f\xB0%02.0f'" $deg_d $min_d ]
+ } else {
+ set res_str [format "%.0f\xB0" $deg_d ]
+ }
}
}
@@ -1171,15 +1176,15 @@
switch $dms_format {
0 {
- set ecoord [format "%.6f\xB0 %s" [expr abs($eastcoord)] $hem_str ]
+ set ecoord [format "%.6f\xB0 %s" [expr abs($eastcoord)] $hem_str ]
}
1 {
- set ecoord [format "%3.0f\xB0 %02.4f' %s" \
- $deg_d $min_f $hem_str ]
+ set ecoord [format "%3.0f\xB0 %02.4f' %s" \
+ $deg_d $min_f $hem_str ]
}
2 {
- set ecoord [format "%3.0f\xB0%02.0f'%06.3f\"%s" \
- $deg_d $min_d $sec_f $hem_str ]
+ set ecoord [format "%3.0f\xB0%02.0f'%06.3f\"%s" \
+ $deg_d $min_d $sec_f $hem_str ]
}
}
@@ -1205,10 +1210,8 @@
set ncoord [format "%.6f\xB0 %s" [expr abs($northcoord)] $hem_str ]
}
1 {
-
set ncoord [format "%2.0f\xB0 %02.4f' %s" \
$deg_d $min_f $hem_str ]
-
}
2 {
set ncoord [format "%2.0f\xB0%02.0f'%06.3f\"%s" \
@@ -1244,7 +1247,7 @@
foreach attr $zoom_attrs {
lappend region $monitor_zooms($mon,1,$attr)
}
-
+
# If explore mode is enabled, set region geometry to match the canvas
# and set map resolution proportional to map size to maintain constant
# numbers of pixels in display.
@@ -1252,36 +1255,28 @@
# Set the region extents to the smallest region no smaller than the canvas
set canvas_ar [expr {1.0 * $canvas_w($mon) / $canvas_h($mon)}]
foreach {n s e w} [MapCanvas::shrinkwrap 1 [lrange $region 0 3] $canvas_ar] {break}
- # In Lat/Lon N and S can not be larger than 90!
-# FIXME:
-#puts "-> n=$n s=$s e=$e w=$w"
- if { $proj_is_ll } {
- if { $n > 90 } {
- set n 90
- tk_messageBox -type ok -icon warning -parent .mapcan($mon) \
- -message [G_msg "Cannot explore beyond the poles: switching into constrained mode"] \
- -title [G_msg "Switching to constrained mode"]
- MapCanvas::exploremode $mon 0
- }
- if { $s < -90 } {
- set s -90
- tk_messageBox -type ok -icon warning -parent .mapcan($mon) \
- -message [G_msg "Cannot explore beyond the poles: switching into constrained mode"] \
- -title [G_msg "Switching to constrained mode"]
- MapCanvas::exploremode $mon 0
- }
- }
-#puts "=> n=$n s=$s e=$e w=$w"
- set expanded_region "$n $s $e $w"
+
+ set expanded_region "$n $s $e $w"
+ set ns [expr $n - $s]
+ set ew [expr $e - $w]
+
+ # adjust for latlon locations
+ if {$proj_is_ll} {
+ if {$ns > 180} {set ns 180}
+ if {$ew > 360} {set ew 360}
+ if {$ew < 0} {set ew [expr $ew + 360]}
+ }
+
# Calculate the resolutions proportional to the map size
- set explore_nsres [expr {1.0 * ($n - $s) / $canvas_h($mon)}]
- set explore_ewres [expr {1.0 * ($e - $w) / $canvas_w($mon)}]
- set explore_rows [expr round(abs($n-$s)/$explore_nsres)]
- set explore_cols [expr round(abs($e-$w)/$explore_ewres)]
+ set explore_nsres [expr {1.0 * ($ns) / $canvas_h($mon)}]
+ set explore_ewres [expr {1.0 * ($ew) / $canvas_w($mon)}]
+ set explore_rows [expr round(abs($ns)/$explore_nsres)]
+ set explore_cols [expr round(abs($ew)/$explore_ewres)]
lappend expanded_region $explore_nsres $explore_ewres $explore_rows $explore_cols
set region $expanded_region
- }
+ }
+
# create region information string for status bar message
set rows [lindex $region 6]
set cols [lindex $region 7]
@@ -1290,19 +1285,19 @@
if { $nsres == $ewres || $exploremode($mon) } {
if { $proj_is_ll } {
- set res_str [MapCanvas::fancy_ll_res $nsres]
+ set res_str [MapCanvas::fancy_ll_res $nsres]
} else {
- set res_str [format "%g" $nsres]
+ set res_str [format "%g" $nsres]
}
set MapCanvas::regionstr [format [G_msg "Display: rows=%d columns=%d resolution=%s\
$mapunits"] $rows $cols $res_str]
} else {
if { $proj_is_ll } {
- set MapCanvas::regionstr [format [G_msg "Display: rows=%d cols=%d N-S res=%s E-W res=%s"] \
- $rows $cols [MapCanvas::fancy_ll_res $nsres] [MapCanvas::fancy_ll_res $ewres]]
+ set MapCanvas::regionstr [format [G_msg "Display: rows=%d cols=%d N-S res=%s E-W res=%s"] \
+ $rows $cols [MapCanvas::fancy_ll_res $nsres] [MapCanvas::fancy_ll_res $ewres]]
} else {
- set MapCanvas::regionstr [format [G_msg "Display: rows=%d cols=%d N-S res=%g E-W res=%g"] \
- $rows $cols $nsres $ewres]
+ set MapCanvas::regionstr [format [G_msg "Display: rows=%d cols=%d N-S res=%g E-W res=%g"] \
+ $rows $cols $nsres $ewres]
}
}
@@ -1319,6 +1314,7 @@
variable monitor_zooms
variable zoomhistories
variable zoom_attrs
+ global proj_is_ll
# Demote all of the zoom history
for {set i $zoomhistories} {$i > 1} {incr i -1} {
@@ -1330,9 +1326,9 @@
# If resolution values aren't present we just use existing values.
set present_attrs [lrange $zoom_attrs 0 [expr {[llength $args] - 1}]]
-
+
foreach value $args attr $present_attrs {
- set monitor_zooms($mon,1,$attr) $value
+ set monitor_zooms($mon,1,$attr) $value
}
}
@@ -1365,7 +1361,8 @@
# Zoom to something loaded from a g.region command
proc MapCanvas::zoom_gregion {mon args} {
global devnull
-
+ global proj_is_ll
+
if {![catch {open [concat "|g.region" "-ugp" $args "2> $devnull"] r} input]} {
while {[gets $input line] >= 0} {
if { [regexp -nocase {^([a-z]+)=(.*)$} $line trash key value] } {
@@ -1397,6 +1394,24 @@
# recalculate region north and east in even multiple of resolution
set parts(e) [expr $parts(w) + $width]
set parts(n) [expr $parts(s) + $height]
+
+ # Limit extents for latlon regions
+ if {$proj_is_ll} {
+ if {$parts(n) > 90} {set parts(n) 90}
+ if {$parts(s) > 90} {set parts(s) 90}
+ if {$parts(n) < -90} {set parts(n) -90}
+ if {$parts(s) < -90} {set parts(s) -90}
+
+ while {$parts(e) > 360} {set parts(e) [expr $parts(e) - 360]}
+ while {$parts(e) < -360} {set parts(e) [expr $parts(e) + 360]}
+ while {$parts(w) > 360} {set parts(w) [expr $parts(w) - 360]}
+ while {$parts(w) < -360} {set parts(w) [expr $parts(w) + 360]}
+
+ if {$parts(w) > 180 && $parts(w) <= 360} {set parts(w) [expr {$parts(w) - 360}]}
+ if {$parts(w) < -180 && $parts(w) >= -360} {set parts(w) [expr {$parts(w) + 360}]}
+ if {$parts(e) > 180 && $parts(e) <= 360} {set parts(e) [expr {$parts(e) - 360}]}
+ if {$parts(e) < -180 && $parts(e) >= -360} {set parts(e) [expr {$parts(e) + 360}]}
+ }
MapCanvas::zoom_new $mon $parts(n) $parts(s) $parts(e) \
$parts(w) $parts(nsres) $parts(ewres) $parts(rows) $parts(cols)
@@ -1459,7 +1474,7 @@
}
if {[catch {eval [list exec -- $cmd] $args $options >& $devnull} error]} {
- GmLib::errmsg $error [G_msg "Error setting region"]
+ GmLib::errmsg $error [G_msg "Error setting region 2"]
}
}
@@ -1568,14 +1583,19 @@
variable areaY1
variable areaX2
variable areaY2
+ global proj_is_ll
set clickzoom 0
-
+
# get display extents in geographic coordinates
set dispnorth [scry2mapn $mon 0]
set dispsouth [scry2mapn $mon $canvas_h($mon)]
set dispeast [scrx2mape $mon $canvas_w($mon)]
set dispwest [scrx2mape $mon 0]
+ set disp_ns [expr $dispnorth - $dispsouth]
+ set disp_ew [expr $dispeast - $dispwest]
+
+ if {$proj_is_ll && $disp_ew < 0} {set disp_ew [expr $disp_ew + 360]}
# minimum zoom by rectangle size = 15pix. For users with shaky hends or jerky mouses
if {abs($areaX2($mon)-$areaX1($mon)) < 15 && abs($areaY2($mon)-$areaY1($mon)) < 15 } {
@@ -1604,10 +1624,11 @@
set east [scrx2mape $mon $cright]
set west [scrx2mape $mon $cleft]
# (this is all you need to zoom in with box)
-
+
# if click and no drag, zoom in or out by fraction of original area and center on the click spot
if {($areaX2($mon) == 0) && ($areaY2($mon) == 0)} {set clickzoom 1}
- # get first click location in map coordinates for recentering with 1-click zooming
+
+ # get first click location in map coordinates for recentering with 1-click zooming
set newcenter_n [scry2mapn $mon $areaY1($mon)]
set newcenter_e [scrx2mape $mon $areaX1($mon)]
@@ -1626,24 +1647,39 @@
# recenters region in display window at spot clicked
if {$clickzoom == 1} {
# calculate amount to zoom in or out in geographic distance
- set nsscale [expr (($dispnorth - $dispsouth) - ($dispnorth - $dispsouth)/sqrt(2))/2]
- set ewscale [expr (($dispeast - $dispwest) - ($dispeast - $dispwest)/sqrt(2))/2]
+ set nsscale [expr ($disp_ns - $disp_ns/sqrt(2))/2]
+ set ewscale [expr ($disp_ew - $disp_ew/sqrt(2))/2]
if {$zoom == 1} {
# zoom in
set north [expr {$dispnorth - $nsscale + $shift_n}]
set south [expr {$dispsouth + $nsscale + $shift_n}]
- set east [expr {$dispeast - $ewscale + $shift_e}]
- set west [expr {$dispwest + $ewscale + $shift_e}]
+ set east [expr {$dispeast - $ewscale + $shift_e}]
+ set west [expr {$dispwest + $ewscale + $shift_e}]
} elseif {$zoom == -1} {
# zoom out
- set north [expr {$dispnorth + $nsscale + $shift_n}]
- set south [expr {$dispsouth - $nsscale + $shift_n}]
- set east [expr {$dispeast + $ewscale + $shift_e}]
- set west [expr {$dispwest - $ewscale + $shift_e}]
- }
- }
+ if {$proj_is_ll && $disp_ns >= 178} {
+ # Limit extents for latlon regions
+ set north $dispnorth
+ set south $dispsouth
+ } else {
+ # shift and scale
+ set north [expr {$dispnorth + $nsscale + $shift_n}]
+ set south [expr {$dispsouth - $nsscale + $shift_n}]
+ }
+
+ if {$proj_is_ll && $disp_ew >= 358} {
+ # if the disp_ew is 360 or more, just shift the center don't rescale
+ set east [expr {$dispeast + $shift_e}]
+ set west [expr {$dispwest + $shift_e}]
+ set east [expr {$dispeast + $shift_e}]
+ set west [expr {$dispwest + $shift_e}]
+ } else {
+ set east [expr {$dispeast + $ewscale + $shift_e}]
+ set west [expr {$dispwest - $ewscale + $shift_e}]
+ }
+ }
+ }
-
# zoom out with box
# box determines zoom out proportion, longest box dimension determines zoom,
# and box center becomes region center. Zoom out relative to the geographic
@@ -1653,53 +1689,93 @@
# Calculate the box geometry--to be used for new region geometry
set box_ns [expr $north-$south]
set box_ew [expr $east-$west]
+
+ # reset for latlon location
+ if {$proj_is_ll && $box_ew < 0} {set box_ew [expr 360 - abs($box_ew)]}
+
# calcuate aspect ratio for zoom box
set box_aspect [expr $box_ns/$box_ew]
+
# calculate zoomout ratio for longest box dimension
if { $box_ns > $box_ew } {
- set zoomratio [expr ($dispnorth - $dispsouth)/$box_ns]
- set new_ns [expr ($dispnorth - $dispsouth) * $zoomratio]
+ set zoomratio [expr ($disp_ns)/$box_ns]
+ set new_ns [expr $disp_ns * $zoomratio]
set new_ew [expr $new_ns / $box_aspect]
} else {
- set zoomratio [expr ($dispeast - $dispwest)/$box_ew]
- set new_ew [expr ($dispeast - $dispwest) * $zoomratio]
+ set zoomratio [expr ($disp_ew)/$box_ew]
+ set new_ew [expr ($disp_ew) * $zoomratio]
set new_ns [expr $new_ew * $box_aspect]
}
# get zoom-out box center
- set boxcenter_n [expr $south + (($north - $south)/2)]
- set boxcenter_e [expr $west + (($east - $west)/2)]
+ set boxcenter_n [expr $south + ($box_ns/2)]
+
+ # reset for latlon location
+ if {$proj_is_ll && $box_ew < 0} {set box_ew [expr 360 - abs($box_ew)]}
+
+ set boxcenter_e [expr $west + ($box_ew/2)]
# zoom out to new extents
- set north [expr $boxcenter_n + ($new_ns/2)]
- set south [expr $boxcenter_n - ($new_ns/2)]
- set east [expr $boxcenter_e + ($new_ew/2)]
- set west [expr $boxcenter_e - ($new_ew/2)]
- }
+ if {$proj_is_ll && $disp_ns >= 178} {
+ # limits for latlon locations
+ set north $dispnorth
+ set south $dispsouth
+ } else {
+ set north [expr $boxcenter_n + ($new_ns/2)]
+ set south [expr $boxcenter_n - ($new_ns/2)]
+ }
+ if {$proj_is_ll && $disp_ew >= 358} {
+ # if the disp_ew is 360 or more, just shift the center don't rescale
+ set east [expr $dispeast + ($oldcenter_e - $boxcenter_e)]
+ set west [expr $dispwest + ($oldcenter_e - $boxcenter_e)]
+ } else {
+ set east [expr $boxcenter_e + ($new_ew/2)]
+ set west [expr $boxcenter_e - ($new_ew/2)]
+ }
+ }
+
+
#set starting point (sw corner)
- set west [expr $ewres*round($west/$ewres)]
+ set west [expr $ewres*round($west/$ewres)]
set south [expr round($south/$nsres)*$nsres]
# get original width and height
- set width [expr abs($east - $west)]
+ set width [expr abs($east - $west)]
set height [expr abs($north - $south)]
-
+
# get columns and rows rounded to nearest multiple of resolution
set cols [expr round($width/$ewres)]
set rows [expr round($height/$nsres)]
# reset width and height in even multiples of resolution
- set width [expr $cols * $ewres]
+ set width [expr $cols * $ewres]
set height [expr $rows * $nsres]
# recalculate region north and east in even multiple of resolution
- set east [expr $west + $width]
+ set east [expr $west + $width]
set north [expr $south + $height]
+ # Limit extents for latlon regions
+ if {$proj_is_ll} {
+ if {$north > 90} {set north 90}
+ if {$south > 90} {set south 90}
+ if {$north < -90} {set north -90}
+ if {$south < -90} {set south -90}
+
+ while {$east > 360} {set east [expr $east - 360]}
+ while {$east < -360} {set east [expr $east + 360]}
+ while {$west > 360} {set west [expr $west - 360]}
+ while {$west < -360} {set west [expr $west + 360]}
+
+ if {$west > 180 && $west <= 360} {set west [expr {$west - 360}]}
+ if {$west < -180 && $west >= -360} {set west [expr {$west + 360}]}
+ if {$east > 180 && $east <= 360} {set east [expr {$east - 360}]}
+ if {$east < -180 && $east >= -360} {set east [expr {$east + 360}]}
+ }
- MapCanvas::zoom_new $mon $north $south $east $west $nsres $ewres $rows $cols
-
+ MapCanvas::zoom_new $mon $north $south $east $west $nsres $ewres $rows $cols
+
# redraw map
$can($mon) delete map$mon
$can($mon) delete area area2
@@ -1737,10 +1813,11 @@
bind $can($mon) <B1-Motion> {
global mon
+
set scrxmov %x
set scrymov %y
set eastcoord [format $outfmt_coords [eval MapCanvas::scrx2mape $mon %x] ]
- set eastcoord [format $outfmt_coords [eval MapCanvas::scrx2mape $mon %x] ]
+# set eastcoord [format $outfmt_coords [eval MapCanvas::scrx2mape $mon %x] ]
if { $proj_is_ll } {
set northcoord [eval MapCanvas::scry2mapn $mon %y]
set coords($mon) [eval MapCanvas::fancy_ll $eastcoord $northcoord]
@@ -1795,15 +1872,12 @@
}
proc MapCanvas::pan { mon } {
- variable start_x
- variable start_y
variable from_x
variable from_y
variable to_x
variable to_y
variable can
- variable can
- variable monitor_zooms
+ global proj_is_ll
# get map coordinate shift
set from_e [scrx2mape $mon $from_x]
@@ -1813,13 +1887,13 @@
# get region extents
foreach {map_n map_s map_e map_w} [MapCanvas::currentzoom $mon] {break}
-
+
# set new region extents
set north [expr {$map_n - ($to_n - $from_n)}]
set south [expr {$map_s - ($to_n - $from_n)}]
set east [expr {$map_e - ($to_e - $from_e)}]
set west [expr {$map_w - ($to_e - $from_e)}]
-
+
# reset region and redraw map
MapCanvas::zoom_new $mon $north $south $east $west
@@ -1986,8 +2060,6 @@
set liney1 $liney2
}
-
-
# format length numbers and units in a nice way, as a function of length
proc MapCanvas::fmt_length { dist } {
@@ -2176,21 +2248,24 @@
variable canvas_w
variable canvas_h
variable monitor_zooms
+ global proj_is_ll
-
# get region extents
foreach {n s e w} [MapCanvas::currentzoom $mon] {break}
# calculate dimensions
-
set north_extent($mon) [expr {1.0*$n}]
set south_extent($mon) [expr {1.0*$s}]
set east_extent($mon) [expr {1.0*$e}]
set west_extent($mon) [expr {1.0*$w}]
-
+
set map_ew($mon) [expr {$east_extent($mon) - $west_extent($mon)}]
set map_ns($mon) [expr {$north_extent($mon) - $south_extent($mon)}]
-
+
+ if {$proj_is_ll} {
+ if {$map_ew($mon) < 0} {set map_ew($mon) [expr $map_ew($mon) + 360]}
+ }
+
# get current screen geometry
if { [info exists "mapimg.$mon"] } {
set scr_lr($mon) [image width "mapimg.$mon"]
@@ -2216,9 +2291,9 @@
# calculate screen dimensions and offsets
if { $map2scrx_conv($mon) > $map2scry_conv($mon) } {
- set map2scrx_conv($mon) $map2scry_conv($mon)
+ set map2scrx_conv($mon) $map2scry_conv($mon)
} else {
- set map2scry_conv($mon) $map2scrx_conv($mon)
+ set map2scry_conv($mon) $map2scrx_conv($mon)
}
}
@@ -2251,8 +2326,15 @@
variable north_extent
variable scr_top
variable map2scry_conv
+ global proj_is_ll
- return [expr {$north_extent($mon) - (($y - $scr_top($mon)) / $map2scry_conv($mon))}]
+ set coord [expr {$north_extent($mon) - (($y - $scr_top($mon)) / $map2scry_conv($mon))}]
+
+ # set for latlon location
+ if {$proj_is_ll && $coord > 90} {set coord 90}
+ if {$proj_is_ll && $coord < -90} {set coord -90}
+
+ return $coord
}
# screen x to map east
@@ -2260,8 +2342,19 @@
variable west_extent
variable scr_left
variable map2scrx_conv
+ global proj_is_ll
- return [expr {$west_extent($mon) + (($x - $scr_left($mon)) / $map2scrx_conv($mon))}]
+ set coord [expr {$west_extent($mon) + (($x - $scr_left($mon)) / $map2scrx_conv($mon))}]
+
+ # calculate for latlon location
+ if {$proj_is_ll } {
+ while {$coord > 360} {set coord [expr $coord - 360]}
+ while {$coord < -360} {set coord [expr $coord + 360]}
+ if {$coord > 180 && $coord <= 360 } {set coord [expr {$coord - 360}]}
+ if {$coord < -180 && $coord >= -360} {set coord [expr {$coord + 360}]}
+ }
+
+ return $coord
}
###############################################################################
More information about the grass-commit
mailing list