[postgis-users] Using two tables in mapserver

Jan Hartmann jhart at frw.uva.nl
Fri Sep 6 08:19:15 PDT 2002


Daryl,

There are many solutions for creating maps based on more than one table. 
I generally use a subselect in the DATA statement

LAYER
CONNECTIONTYPE POSTGIS
CONNECTION "your PG server"
DATA "the_geom from
         (  select map.the_geom, data.myvar
            from maptable as map, datatable as data
            where map.sid = data.sid
            and (... more filter conditions ... )
          ) as foo
      "
     CLASS
        expression ([myvar] > 1 and [myvar] < 10)
        color 10 20 30
     END
     CLASS
         expression ([myvar] >=10 and [myvar] < 20)
         color 20 30 40
      END
      etc ...
END

I don't think you should use MapServer's FILTER statement. I don't know 
if it works on a PostGIS table, but doing your filtering in PostgreSQL 
is anyhow much cleaner.

As you can see, the "myvar" variable in the subselect clause is 
available to MapServer in its class expressions. This doesn't have to be 
a table variable: you can just as well use a computed variable, provided 
you give it a synonym, so MapServer can refer to it:

the_geom from
     (  select map.the_geom,
        case when data.myvar> 1 and data.myvar < 10 then 1
             when data.myvar >=10 and data.myvar < 20 then 2
        end as mycolor
        from maptable as map, datatable as data
        where map.sid = data.sid
      ) as foo

In this case you can use CLASS expressions like:

CLASSITEM mycolor
CLASS
     expression 1
     color 10 20 30
END
CLASS
     expression 2
     color 20 30 40
END
etc ...

For simple cases you can let MapServer itself take care of the class 
computations, as in the first example. With multiple tables and complex 
computations, the second way quickly becomes more attractive.

Performance should be good, PROVIDED you put indices on your variables: 
GIST for geometry, and regular ones for every field you use as a link.

BTW the reason your DATA statement dies so horribly is that you use two 
tables without using a join (where a.var=b.var). PostgreSQL will try to 
return the cross product of both tables (every row of a combined with 
every row of b)!

Hope this helps. Took me some time to figure out!

Jan

Daryl Herzmann wrote:
> 
> I have a database with two tables.
> 
> Table (a) has my data in it.  One of the columns is called sid, which is 
> an identifier for the data point.
> 
> Table (b) has the geometry info with a unique column called sid, which is 
> the same as sid in table a.
> 
> So with Mapserver, I would like to cross-reference these tables.  I bet 
> dollars to donuts, that I am doing something stupid here!!  Here are the 
> relevant .map lines
> 
> DATA "b.geom from tablea a, tableb b"
> FILTER "b.sid = a.sid and a.day = '2000-02-10'"
> 
> This dies a horrible death, since OID::text is ambiguous.  And based on 
> the assembled query, there are other problems....
> 
> I could put a geom column on tablea and make it work, but I would like 
> something more elegant!  Basically, I have many tables and would like them 
> all to use the geom information in one table.  Maybe the performance would 
> be too poor?  tableb has only 500 entries in it, but the data tables have 
> 200 million rows or so combined.
> 

Jan Hartmann
Department of Geography
University of Amsterdam
jhart at frw.uva.nl





More information about the postgis-users mailing list