Ticket #1107: 1107_bounds.diff

File 1107_bounds.diff, 11.2 KB (added by Knut Arne Bjørndal, 11 years ago)

Patch for osmarender/xslt and or/p

  • orp/SAXOsmHandler.pm

    === orp/SAXOsmHandler.pm
    ==================================================================
     
    4343#--------------------------------------------------------------------
    4444sub new
    4545{
    46     my ($type, $node, $way, $relation) = @_;
     46    my ($type, $node, $way, $relation, $bounds) = @_;
    4747   
    4848    return bless {current  => undef,
    4949                  node     => $node,
    5050                  way      => $way,
    51                   relation => $relation }, $type;
     51                  relation => $relation,
     52                  bounds   => $bounds }, $type;
    5253}
    5354
    5455
     
    150151        $self->{current}{layer} = $element->{Attributes}{v}
    151152            if $element->{Attributes}{k} eq "layer";
    152153    }
     154    elsif ($element->{Name} eq 'bounds')
     155    {
     156        my $b = $self->{bounds}; # Just a shortcut
     157        my $minlat = $element->{Attributes}{minlat};
     158        my $minlon = $element->{Attributes}{minlon};
     159        my $maxlat = $element->{Attributes}{maxlat};
     160        my $maxlon = $element->{Attributes}{maxlon};
     161
     162        $b->{minlat} = $minlat if !defined($b->{minlat}) || $minlat < $b->{minlat};
     163        $b->{minlon} = $minlon if !defined($b->{minlon}) || $minlon < $b->{minlon};
     164        $b->{maxlat} = $maxlat if !defined($b->{maxlat}) || $maxlat > $b->{maxlat};
     165        $b->{maxlon} = $maxlon if !defined($b->{maxlon}) || $maxlon > $b->{maxlon};
     166    }
    153167    else
    154168    {
    155169        # ignore for now
  • orp/orp.pl

    === orp/orp.pl
    ==================================================================
     
    135135our $node_storage = {};
    136136our $way_storage = {};
    137137our $relation_storage = {};
     138my %data_bounds = ();
    138139our $text_index = {};
    139140our $meter2pixel = {};
    140141our %symbols = ();
    141142our $labelRelations = {};
    142143
    143 my $handler = SAXOsmHandler->new($node_storage, $way_storage, $relation_storage);
     144my $handler = SAXOsmHandler->new($node_storage, $way_storage, $relation_storage, \%data_bounds);
    144145my $parser = XML::Parser::PerlSAX->new(Handler => $handler);
    145146my $rule_file = "rule.xml";
    146147my $debug_opts = '';
    147148my $output_file;
     149my %opt_bounds;
    148150my $bbox;
    149151my %referenced_ways;
    150152
     
    172174GetOptions("rule=s"    => \$rule_file,
    173175           "debug=s"   => \$debug_opts,
    174176           "outfile=s" => \$output_file,
    175            "bbox=s"    => \$bbox);
     177           "minlat=f"  => \$opt_bounds{minlat},
     178           "minlon=f"  => \$opt_bounds{minlon},
     179           "maxlat=f"  => \$opt_bounds{maxlat},
     180           "maxlon=f"  => \$opt_bounds{maxlon},
     181           "bbox=s"    => \$bbox) or usage('');
    176182
    177183for my $key(split(/,/, $debug_opts))
    178184{
     
    183189    $debug->{$key} = 1;
    184190}
    185191
     192if ($bbox)
     193{
     194    usage("Error: Both bbox and one of minlat/minlon/maxlat/maxlon given")
     195        if @opt_bounds{qw(minlat minlon maxlat maxlon)};
     196    ($opt_bounds{minlat}, $opt_bounds{minlon}, $opt_bounds{maxlat}, $opt_bounds{maxlon}) = split(/,/, $bbox);
     197}
     198
    186199my $rules = XML::XPath->new(filename => $rule_file);
    187200my $data = get_variable("data", "");
    188201
     
    301314my $extraWidth = ($showBorder eq "yes") ? 3 : 0;
    302315my $extraHeight = ($title eq "" and $showBorder eq "yes") ? 3 : 0;
    303316
    304 #  Calculate the size of the bounding box based on data
    305 my $maxlon = -500;
    306 my $maxlat = -500;
    307 my $minlon = 500;
    308 my $minlat = 500;
     317# Find out what bounds to render
    309318
    310 foreach (values(%$node_storage))
     319my ($minlat, $minlon, $maxlat, $maxlon);
     320
     321if (@opt_bounds{qw(minlat minlon maxlat maxlon)}) # Given on command line
    311322{
    312     $maxlon = $_->{"lon"} if ($_->{"lon"} > $maxlon);
    313     $maxlat = $_->{"lat"} if ($_->{"lat"} > $maxlat);
    314     $minlon = $_->{"lon"} if ($_->{"lon"} < $minlon);
    315     $minlat = $_->{"lat"} if ($_->{"lat"} < $minlat);
     323    $minlat = $opt_bounds{minlat};
     324    $minlon = $opt_bounds{minlon};
     325    $maxlat = $opt_bounds{maxlat};
     326    $maxlon = $opt_bounds{maxlon};
    316327}
    317 
    318 # if explicit bounds are given in the rules file, honour them
    319 if ($rules->find("//rules/bounds"))
     328elsif ($rules->find('//rules/bounds')) # Given in rules file
    320329{
    321     $minlat = get_variable("bounds/minlat");
    322     $minlon = get_variable("bounds/minlon");
    323     $maxlat = get_variable("bounds/maxlat");
    324     $maxlon = get_variable("bounds/maxlon");
     330    $minlat = get_variable('bounds/minlat');
     331    $minlon = get_variable('bounds/minlon');
     332    $maxlat = get_variable('bounds/maxlat');
     333    $maxlon = get_variable('bounds/maxlon');
    325334}
    326 
    327 # FIXME find bound element in .osm file and honour it
    328 
    329 # if explicit bound are given on command line, honour them
    330 if (defined($bbox))
     335elsif (%data_bounds) # Given as <bounds> element(s) in data file
    331336{
    332     ($minlat, $minlon, $maxlat, $maxlon) = split(/,/, $bbox);
     337    $minlat = $data_bounds{minlat};
     338    $minlon = $data_bounds{minlon};
     339    $maxlat = $data_bounds{maxlat};
     340    $maxlon = $data_bounds{maxlon};
    333341}
     342else # Fallback to calculating based on nodes in data
     343{
     344    foreach (values(%$node_storage))
     345    {
     346        $maxlon = $_->{"lon"} if (!defined($maxlon) || $_->{"lon"} > $maxlon);
     347        $maxlat = $_->{"lat"} if (!defined($maxlat) || $_->{"lat"} > $maxlat);
     348        $minlon = $_->{"lon"} if (!defined($minlon) || $_->{"lon"} < $minlon);
     349        $minlat = $_->{"lat"} if (!defined($minlat) || $_->{"lat"} < $minlat);
     350    }
     351}
    334352
    335353our $scale = get_variable("scale", 1);
    336354our $symbolScale = get_variable("symbolScale", 1);
     
    13551373   -d|--debug=list      specify list of debug options
    13561374   -o|--outfile=name    specify output file (default: same as input, with .svg)
    13571375   -r|--rule=file.xml   specify the rule file to use (default: rule.xml)
    1358    -b|--bbox=minLat,minLon,maxLat,maxLon specify bounding box
     1376   --minlat             Minimum latitude to render
     1377   --minlon             Minimum longitude to render
     1378   --maxlat             Maximum latitude to render
     1379   --maxlon             Maximum longitude to render
     1380   -b|--bbox=minLat,minLon,maxLat,maxLon specify bounding box (as alternative to the specific options)
    13591381
    13601382EOF
    13611383    exit(1);
  • xslt/osmarender.xsl

    === xslt/osmarender.xsl
    ==================================================================
     
    144144    </xsl:choose>
    145145  </xsl:variable>
    146146
    147   <!-- Calculate the size of the bounding box based on the file content -->
    148   <xsl:variable name="bllat">
    149     <xsl:for-each select="$data/osm/node/@lat">
    150       <xsl:sort data-type="number" order="ascending"/>
    151       <xsl:if test="position()=1">
    152         <xsl:value-of select="."/>
    153       </xsl:if>
    154     </xsl:for-each>
    155   </xsl:variable>
    156   <xsl:variable name="bllon">
    157     <xsl:for-each select="$data/osm/node/@lon">
    158       <xsl:sort data-type="number" order="ascending"/>
    159       <xsl:if test="position()=1">
    160         <xsl:value-of select="."/>
    161       </xsl:if>
    162     </xsl:for-each>
    163   </xsl:variable>
    164   <xsl:variable name="trlat">
    165     <xsl:for-each select="$data/osm/node/@lat">
    166       <xsl:sort data-type="number" order="descending"/>
    167       <xsl:if test="position()=1">
    168         <xsl:value-of select="."/>
    169       </xsl:if>
    170     </xsl:for-each>
    171   </xsl:variable>
    172   <xsl:variable name="trlon">
    173     <xsl:for-each select="$data/osm/node/@lon">
    174       <xsl:sort data-type="number" order="descending"/>
    175       <xsl:if test="position()=1">
    176         <xsl:value-of select="."/>
    177       </xsl:if>
    178     </xsl:for-each>
    179   </xsl:variable>
     147  <!-- Calculate bounding box.
     148       Use the first given of min/max lat/lon parameters, bounds element from rules,
     149       bounds elements from data or fallback to calculating based on file content -->
     150
    180151  <xsl:variable name="bottomLeftLatitude">
    181152    <xsl:choose>
    182153      <xsl:when test="$minlat">
     
    186157        <xsl:value-of select="/rules/bounds/@minlat"/>
    187158      </xsl:when>
    188159      <xsl:when test="$data/osm/bounds">
    189         <xsl:value-of select="$data/osm/bounds/@minlat"/>
     160        <xsl:for-each select="$data/osm/bounds/@minlat">
     161          <xsl:sort data-type="number" order="ascending"/>
     162          <xsl:if test="position()=1">
     163            <xsl:value-of select="."/>
     164          </xsl:if>
     165        </xsl:for-each>
    190166      </xsl:when>
    191167      <xsl:otherwise>
    192         <xsl:value-of select="$bllat"/>
     168        <xsl:for-each select="$data/osm/node/@lat">
     169          <xsl:sort data-type="number" order="ascending"/>
     170          <xsl:if test="position()=1">
     171            <xsl:value-of select="."/>
     172          </xsl:if>
     173        </xsl:for-each>
    193174      </xsl:otherwise>
    194175    </xsl:choose>
    195176  </xsl:variable>
     
    199180        <xsl:value-of select="$minlon"/>
    200181      </xsl:when>
    201182      <xsl:when test="/rules/bounds">
    202         <xsl:value-of select="/rules/bounds/@minlon"/>
     183        <xsl:for-each select="$data/osm/bounds/@minlon">
     184          <xsl:sort data-type="number" order="ascending"/>
     185          <xsl:if test="position()=1">
     186            <xsl:value-of select="."/>
     187          </xsl:if>
     188        </xsl:for-each>
    203189      </xsl:when>
    204190      <xsl:when test="$data/osm/bounds">
    205         <xsl:value-of select="$data/osm/bounds/@minlon"/>
     191        <xsl:for-each select="$data/osm/bounds/@minlon">
     192          <xsl:sort data-type="number" order="ascending"/>
     193          <xsl:if test="position()=1">
     194            <xsl:value-of select="."/>
     195          </xsl:if>
     196        </xsl:for-each>
    206197      </xsl:when>
    207198      <xsl:otherwise>
    208         <xsl:value-of select="$bllon"/>
     199        <xsl:for-each select="$data/osm/node/@lon">
     200          <xsl:sort data-type="number" order="ascending"/>
     201          <xsl:if test="position()=1">
     202            <xsl:value-of select="."/>
     203          </xsl:if>
     204        </xsl:for-each>
    209205      </xsl:otherwise>
    210206    </xsl:choose>
    211207  </xsl:variable>
     
    218214        <xsl:value-of select="/rules/bounds/@maxlat"/>
    219215      </xsl:when>
    220216      <xsl:when test="$data/osm/bounds">
    221         <xsl:value-of select="$data/osm/bounds/@maxlat"/>
     217        <xsl:for-each select="$data/osm/bounds/@maxlat">
     218          <xsl:sort data-type="number" order="descending"/>
     219          <xsl:if test="position()=1">
     220            <xsl:value-of select="."/>
     221          </xsl:if>
     222        </xsl:for-each>
    222223      </xsl:when>
    223224      <xsl:otherwise>
    224         <xsl:value-of select="$trlat"/>
     225        <xsl:for-each select="$data/osm/node/@lat">
     226          <xsl:sort data-type="number" order="descending"/>
     227          <xsl:if test="position()=1">
     228            <xsl:value-of select="."/>
     229          </xsl:if>
     230        </xsl:for-each>
    225231      </xsl:otherwise>
    226232    </xsl:choose>
    227233  </xsl:variable>
     
    234240        <xsl:value-of select="/rules/bounds/@maxlon"/>
    235241      </xsl:when>
    236242      <xsl:when test="$data/osm/bounds">
    237         <xsl:value-of select="$data/osm/bounds/@maxlon"/>
     243        <xsl:for-each select="$data/osm/bounds/@maxlon">
     244          <xsl:sort data-type="number" order="descending"/>
     245          <xsl:if test="position()=1">
     246            <xsl:value-of select="."/>
     247          </xsl:if>
     248        </xsl:for-each>
    238249      </xsl:when>
    239250      <xsl:otherwise>
    240         <xsl:value-of select="$trlon"/>
     251        <xsl:for-each select="$data/osm/node/@lon">
     252          <xsl:sort data-type="number" order="descending"/>
     253          <xsl:if test="position()=1">
     254            <xsl:value-of select="."/>
     255          </xsl:if>
     256        </xsl:for-each>
    241257      </xsl:otherwise>
    242258    </xsl:choose>
    243259  </xsl:variable>