[prev in list] [next in list] [prev in thread] [next in thread]
List: postgis-users
Subject: Re: [postgis-users] Generating new random points throughout an update
From: Brent Wood via postgis-users <postgis-users () lists ! osgeo ! org>
Date: 2023-11-18 22:19:06
Message-ID: 440250066.5558269.1700345946645 () mail ! yahoo ! com
[Download RAW message or body]
[Attachment #2 (multipart/alternative)]
Gotcha...
I'm glad it didn't really make sense to you either. That is sort of what I thought \
might be happening.
Nice to know I'm not a totally lost cause!!!
That works perfectly,
Thanks heaps!!
On Sunday, November 19, 2023 at 11:09:34 AM GMT+13, Regina Obe <lr@pcorp.us> \
wrote:
I'm guessing the reason why your example doesn't work is because the planner is doing \
some serious short-circuiting cause it sees two subselects that are using no \
variables from the updated table.
I suspect this is a bug or some intentional stuff that makes no sense to me. Cause \
I'm pretty sure I've done something like UPDATE sometable SET geom = \
ST_GeneratePoints(somestaticgeom,1);
And gotten different answers. So I suspect it's the subselect throwing it off or it \
is intentionally treating like a constant because that subselect doesn't involve the \
table being updated.
So the trick I see is to incorporate some value from your events table into your \
routine.
Try computing first and then updating like so the below gives me different answers \
for each row.
WITH a AS (
SELECT e.id, ST_Makeline(
ST_GeometryN(
ST_GeneratePoints(
ST_Buffer(
ST_POINTN(s.std_track,1),
0.01),
1),
1), ST_GeometryN(
ST_GeneratePoints(
ST_Buffer(
ST_POINTN(s.std_track,2),
0.01),
1),
1)
) AS geom
FROM events AS e, std_tow AS s
)
UPDATE events
set jittered = a.geom
FROM a
WHERE a.id = events.id;
select ST_AsText(jittered) from events;
the other way to do it, making the planner realize that just cause the code is \
exactly the same and doesn't involve the table being updated, doesn't mean you want \
all your values to be the same, is to incorporate your event id in your randomize \
like so
update events
set jittered = ST_Makeline(
(select ST_GeometryN(
ST_GeneratePoints(
ST_Buffer(
ST_POINTN(std_track,1),
0.01),
1,
(random()*1000)::int + events.id),
1)
from std_tow),
(select ST_GeometryN(
ST_GeneratePoints(
ST_Buffer(
ST_POINTN(std_track,2),
0.01),
1,
(random()*1000)::int + events.id),
1)
from std_tow));
select ST_AsText(jittered) from events;
From: Brent Wood <pcreso@yahoo.com>
Sent: Saturday, November 18, 2023 4:35 PM
To: Regina Obe <lr@pcorp.us>; PostGIS Users Discussion \
<postgis-users@lists.osgeo.org>
Subject: Re: [postgis-users] Generating new random points throughout an update
Thanks for your time & advice Regina, I appreciate it.
I still can't get this to work as I think it should, so have included actual SQL's to \
show what I'm doing, using ST_GeneratePoints() this time...
I create a db & add the postgis extension....
Then create the two tables to test, inserting 3 empty geometries in one & a simple \
linestring in the other:
create table events (id integer,
jittered geometry(LINESTRING,4326));
insert into events (id) values (1);
insert into events (id) values (2);
insert into events (id) values (3);
create table std_tow (id integer,
std_track geometry(LINESTRING,4326));
insert into std_tow values (1, ST_SetSRID(
ST_MakeLine(
\
ST_MakePoint(176,-47),
\
ST_MakePoint(177,-48)
),
4326));
I want to update the empty linestrings in one table (events) with slightly randomised \
versions of the linestring in the other (std_tow).
ST_GeneratePoints() supposedly generates random points (in a polygon created by \
buffering the vertices in the standard linestring) without a seed, so I run it with \
no seed & view the results:
update events
set jittered = ST_Makeline(
(select ST_GeometryN(
ST_GeneratePoints(
ST_Buffer(
ST_POINTN(std_track,1),
0.01),
1),
1)
from std_tow),
(select ST_GeometryN(
ST_GeneratePoints(
ST_Buffer(
ST_POINTN(std_track,2),
0.01),
1),
1)
from std_tow));
select ST_AsText(jittered) from events;
LINESTRING(175.99658281229873 -46.99893493622685,177.0081812507064 \
-47.99873318845546) LINESTRING(175.99658281229873 \
-46.99893493622685,177.0081812507064 -47.99873318845546) \
LINESTRING(175.99658281229873 -46.99893493622685,177.0081812507064 \
-47.99873318845546) (3 rows)
I get three identical linestrings.
I figured I'd use a different integer random seed (between 0 and 1000) in \
ST_GeneratePoints() to force a different result each time:
update events
set jittered = ST_Makeline(
(select ST_GeometryN(
ST_GeneratePoints(
ST_Buffer(
ST_POINTN(std_track,1),
0.01),
1,
(random()*1000)::int),
1)
from std_tow),
(select ST_GeometryN(
ST_GeneratePoints(
ST_Buffer(
ST_POINTN(std_track,2),
0.01),
1,
(random()*1000)::int),
1)
from std_tow));
select ST_AsText(jittered) from events;
LINESTRING(175.9943248467802 -46.996045972449906,176.9919097521138 \
-48.00102135929174) LINESTRING(175.9943248467802 \
-46.996045972449906,176.9919097521138 -48.00102135929174) \
LINESTRING(175.9943248467802 -46.996045972449906,176.9919097521138 \
-48.00102135929174) (3 rows)
I get different vertices from the first attempt, but all 3 records are still the same \
values - despite supposedly having a different seed.
I figure the Postgres query optimiser must be reusing the result from the subqueries \
rather than recalculating it each time, but am not sure, and the optimiser cannot be \
turned off.
What am I doing wrong??? (or how can I do it right!!)
Much appreciated,
Brent
On Sunday, November 19, 2023 at 06:44:16 AM GMT+13, Regina Obe <lr@pcorp.us> wrote:
Well when I run random() I do get a different answer for each run so random behaves \
as I would expect. I didn't look that closely at your query with random.
e.g.
SELECT random()
FROM generate_series(1,100);
Even if within the same row, the random numbers are different:
SELECT random(), random()
FROM generate_series(1,10);
If you were doing random()::integer as input into ST_GeneratePoints, I thought maybe \
that was a typo on your end. Then your random number would only be 0 or 1, which is \
not that random.
So if you really were doing ST_GeneratePoints(geom, random()::integer) then that \
would explain why you got much less than random results with ST_GeneratePoints.
From: Brent Wood <pcreso@yahoo.com>
Sent: Saturday, November 18, 2023 1:29 AM
To: Regina Obe <lr@pcorp.us>; PostGIS Users Discussion \
<postgis-users@lists.osgeo.org>
Subject: Re: [postgis-users] Generating new random points throughout an update
Hi Regina,
The seed was an int generated from random(), so I'd expected to generate a different \
result every time. This didn't happen.
Do I understand that if I omit the seed, I'll get a different point each time by \
default?
Thanks,
Brent
On Saturday, November 18, 2023 at 06:01:37 PM GMT+13, Regina Obe <lr@pcorp.us> wrote: \
If you want the answer different each time, you don't want to feed a seed to \
ST_GeneratePoints.
The seed argument was added because some people wanted to generate the same answer \
for each run.
https://postgis.net/docs/ST_GeneratePoints.html (note the sentence: The optional \
seed is used to regenerate a deterministic sequence of points, and must be greater \
than zero.)
From: postgis-users <postgis-users-bounces@lists.osgeo.org> On Behalf Of Brent Wood \
via postgis-users
Sent: Friday, November 17, 2023 11:53 PM
To: PostGIS Users Discussion <postgis-users@lists.osgeo.org>
Cc: Brent Wood <pcreso@yahoo.com>
Subject: [postgis-users] Generating new random points throughout an update
Hopefully someone can help with a problem I'm having.
I have a table with simple linestrings that I need to create a randomly modified \
version of.
The linestrings represent vessel tracks. I can identify a set of "similar" tracks & \
create a single "average" linestring that is somewhat representative.
Many of the records don't have a linestring, but for statistical purposes I need to \
assign a linestring to each - by creating a jittered version of the average \
linestring so they are not all identical.
The simplest approach I have tried is to use an update with ST_Project() given a \
random() distance & random() direction applied to each vertex in the average line.
I use the first two vertices with ST_Makeline(), then append a vertex for the third \
point, as in the SQL below.
My problem is that every new line is identical. From some Googled hints, I figure the \
optimiser has decided to run random() once & re-use the value instead of running the \
function for every iteration (but I could be wrong!).
Any suggestions as to how I can force a different random result for each record that \
is updated?
I also tried using ST_GeneratePoints() in a buffer around each point, but need to use \
something like (random()::int as the seed, and this seems to do exactly the same - \
valid linestrings are generated, but they are identical, so I'm assuming the seed is \
not being recalculated for each record.
update events
set jittered = ST_MakeLine(
(select ST_Project(
\
ST_POINTN(std_track,1),
\
(random()*5000),
\
radians(random()*360))::geometry from std_tow),
(select ST_Project(
\
ST_PointN(std_track,2),
\
(random()*5000),
\
radians(random()*360))::geometry from std_tow)
);
Thanks,
Brent Wood
[Attachment #5 (text/html)]
<html><head></head><body><div class="ydp688cabceyahoo-style-wrap" \
style="font-family:verdana, helvetica, sans-serif;font-size:16px;"><div></div> <div \
dir="ltr" data-setdir="false">Gotcha...</div><div dir="ltr" \
data-setdir="false"><br></div><div dir="ltr" data-setdir="false">I'm glad it didn't \
really make sense to you either. That is sort of what I thought might be \
happening.<br></div><div dir="ltr" data-setdir="false"><br></div><div dir="ltr" \
data-setdir="false">Nice to know I'm not a totally lost \
cause!!!<br></div><div><br></div><div dir="ltr" data-setdir="false">That works \
perfectly,</div><div dir="ltr" data-setdir="false"><br></div><div dir="ltr" \
data-setdir="false"><br></div><div dir="ltr" data-setdir="false">Thanks \
heaps!!<br></div><div><br></div><div><br></div>
</div><div id="ydp4b316ddfyahoo_quoted_0708346464" \
class="ydp4b316ddfyahoo_quoted">
<div style="font-family:'Helvetica Neue', Helvetica, Arial, \
sans-serif;font-size:13px;color:#26282a;">
<div>
On Sunday, November 19, 2023 at 11:09:34 AM GMT+13, Regina Obe \
<lr@pcorp.us> wrote: </div>
<div><br></div>
<div><br></div>
<div><div id="ydp4b316ddfyiv7486868869"><div><div \
class="ydp4b316ddfyiv7486868869WordSection1"><p \
class="ydp4b316ddfyiv7486868869MsoNormal">I'm guessing the reason why your example \
doesn't work is because the planner is doing some serious short-circuiting cause it \
sees two subselects that are using no variables from the updated table. </p><p \
class="ydp4b316ddfyiv7486868869MsoNormal">I suspect this is a bug or some intentional \
stuff that makes no sense to me. Cause I'm pretty sure I've done something \
like UPDATE sometable SET geom = ST_GeneratePoints(somestaticgeom,1);</p><p \
class="ydp4b316ddfyiv7486868869MsoNormal">And gotten different answers. So I \
suspect it's the subselect throwing it off or it is intentionally treating like a \
constant because that subselect doesn't involve the table being updated.</p><p \
class="ydp4b316ddfyiv7486868869MsoNormal"> </p><p \
class="ydp4b316ddfyiv7486868869MsoNormal">So the trick I see is to incorporate some \
value from your events table into your routine.</p><p \
class="ydp4b316ddfyiv7486868869MsoNormal"> </p><p \
class="ydp4b316ddfyiv7486868869MsoNormal">Try computing first and then updating like \
so the below gives me different answers for each row.</p><p \
class="ydp4b316ddfyiv7486868869MsoNormal"> </p><p \
class="ydp4b316ddfyiv7486868869MsoNormal">WITH a AS (</p><p \
class="ydp4b316ddfyiv7486868869MsoNormal">SELECT e.id, ST_Makeline(</p><p \
class="ydp4b316ddfyiv7486868869MsoNormal"> \
ST_GeometryN(</p><p class="ydp4b316ddfyiv7486868869MsoNormal"> \
ST_GeneratePoints(</p><p \
class="ydp4b316ddfyiv7486868869MsoNormal"> \
ST_Buffer(</p><p class="ydp4b316ddfyiv7486868869MsoNormal"> &nb \
sp; \
ST_POINTN(s.std_track,1),</p><p \
class="ydp4b316ddfyiv7486868869MsoNormal"> &n \
bsp; \
0.01),</p><p class="ydp4b316ddfyiv7486868869MsoNormal"> \
1),</p><p class="ydp4b316ddfyiv7486868869MsoNormal"> \
1), ST_GeometryN(</p><p \
class="ydp4b316ddfyiv7486868869MsoNormal"> \
ST_GeneratePoints(</p><p \
class="ydp4b316ddfyiv7486868869MsoNormal"> \
ST_Buffer(</p><p class="ydp4b316ddfyiv7486868869MsoNormal"> &nb \
sp; \
ST_POINTN(s.std_track,2),</p><p \
class="ydp4b316ddfyiv7486868869MsoNormal"> &n \
bsp; \
0.01),</p><p class="ydp4b316ddfyiv7486868869MsoNormal"> & \
nbsp; \
1),</p><p class="ydp4b316ddfyiv7486868869MsoNormal"> \
1)</p><p class="ydp4b316ddfyiv7486868869MsoNormal"> \
) AS geom</p><p class="ydp4b316ddfyiv7486868869MsoNormal">FROM events AS e, std_tow \
AS s</p><p class="ydp4b316ddfyiv7486868869MsoNormal">)</p><p \
class="ydp4b316ddfyiv7486868869MsoNormal">UPDATE events</p><p \
class="ydp4b316ddfyiv7486868869MsoNormal">set jittered = a.geom</p><p \
class="ydp4b316ddfyiv7486868869MsoNormal">FROM a</p><p \
class="ydp4b316ddfyiv7486868869MsoNormal">WHERE a.id = events.id;</p><p \
class="ydp4b316ddfyiv7486868869MsoNormal">select ST_AsText(jittered) from \
events;</p><p class="ydp4b316ddfyiv7486868869MsoNormal"> </p><p \
class="ydp4b316ddfyiv7486868869MsoNormal">the other way to do it, making the planner \
realize that just cause the code is exactly the same and doesn't involve the table \
being updated, doesn't mean you want all your values to be the same, is to \
incorporate your event id in your randomize like so</p><p \
class="ydp4b316ddfyiv7486868869MsoNormal"> </p><p \
class="ydp4b316ddfyiv7486868869MsoNormal">update events</p><p \
class="ydp4b316ddfyiv7486868869MsoNormal">set jittered = ST_Makeline(</p><p \
class="ydp4b316ddfyiv7486868869MsoNormal"> \
(select ST_GeometryN(</p><p \
class="ydp4b316ddfyiv7486868869MsoNormal"> \
ST_GeneratePoints(</p><p \
class="ydp4b316ddfyiv7486868869MsoNormal"> \
ST_Buffer(</p><p class="ydp4b316ddfyiv7486868869MsoNormal"> &nb \
sp; \
ST_POINTN(std_track,1),</p><p \
class="ydp4b316ddfyiv7486868869MsoNormal"> &n \
bsp; \
0.01),</p><p class="ydp4b316ddfyiv7486868869MsoNormal"> \
1,</p><p class="ydp4b316ddfyiv7486868869MsoNormal"> \
(random()*1000)::int + events.id),</p><p \
class="ydp4b316ddfyiv7486868869MsoNormal"> \
1)</p><p class="ydp4b316ddfyiv7486868869MsoNormal"> \
from std_tow),</p><p \
class="ydp4b316ddfyiv7486868869MsoNormal"> \
(select ST_GeometryN(</p><p \
class="ydp4b316ddfyiv7486868869MsoNormal"> \
ST_GeneratePoints(</p><p \
class="ydp4b316ddfyiv7486868869MsoNormal"> \
ST_Buffer(</p><p class="ydp4b316ddfyiv7486868869MsoNormal"> &nb \
sp; \
ST_POINTN(std_track,2),</p><p \
class="ydp4b316ddfyiv7486868869MsoNormal"> &n \
bsp; \
0.01),</p><p class="ydp4b316ddfyiv7486868869MsoNormal"> & \
nbsp; \
1,</p><p class="ydp4b316ddfyiv7486868869MsoNormal"> \
(random()*1000)::int + events.id),</p><p \
class="ydp4b316ddfyiv7486868869MsoNormal"> \
1)</p><p class="ydp4b316ddfyiv7486868869MsoNormal"> \
from std_tow));</p><p class="ydp4b316ddfyiv7486868869MsoNormal">select \
ST_AsText(jittered) from events;</p><p class="ydp4b316ddfyiv7486868869MsoNormal"> \
</p><p class="ydp4b316ddfyiv7486868869MsoNormal"> </p><p \
class="ydp4b316ddfyiv7486868869MsoNormal"> </p><p \
class="ydp4b316ddfyiv7486868869MsoNormal"> </p><div style="border-width: medium \
medium medium 1.5pt; border-style: none none none solid; border-color: currentcolor \
currentcolor currentcolor blue; padding: 0in 0in 0in 4pt;"><div \
id="ydp4b316ddfyiv7486868869yqt10409" \
class="ydp4b316ddfyiv7486868869yqt8129383420"><div><div style="border-width: 1pt \
medium medium; border-style: solid none none; border-color: rgb(225, 225, 225) \
currentcolor currentcolor; padding: 3pt 0in 0in;"><p \
class="ydp4b316ddfyiv7486868869MsoNormal"><b>From:</b> Brent Wood \
<pcreso@yahoo.com> <br clear="none"><b>Sent:</b> Saturday, November 18, 2023 \
4:35 PM<br clear="none"><b>To:</b> Regina Obe <lr@pcorp.us>; PostGIS Users \
Discussion <postgis-users@lists.osgeo.org><br clear="none"><b>Subject:</b> Re: \
[postgis-users] Generating new random points throughout an update</p></div></div><p \
class="ydp4b316ddfyiv7486868869MsoNormal"> </p><div><div><div><div><p \
class="ydp4b316ddfyiv7486868869MsoNormal"><span \
style="font-size:12.0pt;font-family:sans-serif;color:black;">Thanks for your time \
& advice Regina, I appreciate it.</span></p></div><div><p \
class="ydp4b316ddfyiv7486868869MsoNormal"><span \
style="font-size:12.0pt;font-family:sans-serif;color:black;"> \
</span></p></div><div><p class="ydp4b316ddfyiv7486868869MsoNormal"><span \
style="font-size:12.0pt;font-family:sans-serif;color:black;"> \
</span></p></div><div><p class="ydp4b316ddfyiv7486868869MsoNormal"><span \
style="font-size:12.0pt;font-family:sans-serif;color:black;">I still can't get this \
to work as I think it should, so have included actual SQL's to show what I'm doing, \
using ST_GeneratePoints() this time...</span></p></div><div><p \
class="ydp4b316ddfyiv7486868869MsoNormal"><span \
style="font-size:12.0pt;font-family:sans-serif;color:black;"> \
</span></p></div><div><p class="ydp4b316ddfyiv7486868869MsoNormal"><span \
style="font-size:12.0pt;font-family:sans-serif;color:black;">I create a db & add \
the postgis extension....</span></p></div><div><p \
class="ydp4b316ddfyiv7486868869MsoNormal"><span \
style="font-size:12.0pt;font-family:sans-serif;color:black;"> \
</span></p></div><div><p class="ydp4b316ddfyiv7486868869MsoNormal"><span \
style="font-size:12.0pt;font-family:sans-serif;color:black;">Then create the two \
tables to test, inserting 3 empty geometries in one & a simple linestring in the \
other:</span></p></div><div><p class="ydp4b316ddfyiv7486868869MsoNormal"><span \
style="font-size:12.0pt;font-family:sans-serif;color:black;"> \
</span></p></div><div><p class="ydp4b316ddfyiv7486868869MsoNormal"><i><span \
style="font-size:12.0pt;color:black;">create table events (id \
integer,</span></i><span \
style="font-size:12.0pt;font-family:sans-serif;color:black;"></span></p><div><p \
class="ydp4b316ddfyiv7486868869MsoNormal"><i><span \
style="font-size:12.0pt;color:black;"> \
jittered \
geometry(LINESTRING,4326));</span></i><span \
style="font-size:12.0pt;font-family:sans-serif;color:black;"></span></p></div><div><p \
class="ydp4b316ddfyiv7486868869MsoNormal"><span \
style="font-size:12.0pt;font-family:sans-serif;color:black;"> \
</span></p></div><div><p class="ydp4b316ddfyiv7486868869MsoNormal"><i><span \
style="font-size:12.0pt;color:black;">insert into events (id) values \
(1);</span></i><span \
style="font-size:12.0pt;font-family:sans-serif;color:black;"></span></p></div><div><p \
class="ydp4b316ddfyiv7486868869MsoNormal"><i><span \
style="font-size:12.0pt;color:black;">insert into events (id) values \
(2);</span></i><span \
style="font-size:12.0pt;font-family:sans-serif;color:black;"></span></p></div><div><p \
class="ydp4b316ddfyiv7486868869MsoNormal"><i><span \
style="font-size:12.0pt;color:black;">insert into events (id) values \
(3);</span></i><span \
style="font-size:12.0pt;font-family:sans-serif;color:black;"></span></p></div><div><p \
class="ydp4b316ddfyiv7486868869MsoNormal"><span \
style="font-size:12.0pt;font-family:sans-serif;color:black;"> \
</span></p></div><div><p class="ydp4b316ddfyiv7486868869MsoNormal"><i><span \
style="font-size:12.0pt;color:black;">create table std_tow (id \
integer,</span></i><span \
style="font-size:12.0pt;font-family:sans-serif;color:black;"></span></p></div><div><p \
class="ydp4b316ddfyiv7486868869MsoNormal"><i><span \
style="font-size:12.0pt;color:black;"> \
std_track \
geometry(LINESTRING,4326));</span></i><span \
style="font-size:12.0pt;font-family:sans-serif;color:black;"></span></p></div><div><p \
class="ydp4b316ddfyiv7486868869MsoNormal"><span \
style="font-size:12.0pt;font-family:sans-serif;color:black;"> \
</span></p></div><div><p class="ydp4b316ddfyiv7486868869MsoNormal"><i><span \
style="font-size:12.0pt;color:black;">insert into std_tow values (1, \
ST_SetSRID(</span></i><span \
style="font-size:12.0pt;font-family:sans-serif;color:black;"></span></p></div><div><p \
class="ydp4b316ddfyiv7486868869MsoNormal"><i><span \
style="font-size:12.0pt;color:black;"> \
\
ST_MakeLine(</span></i><span \
style="font-size:12.0pt;font-family:sans-serif;color:black;"></span></p></div><div><p \
class="ydp4b316ddfyiv7486868869MsoNormal"><i><span \
style="font-size:12.0pt;color:black;"> \
ST_MakePoint(176,-47),</span></i><span \
style="font-size:12.0pt;font-family:sans-serif;color:black;"></span></p></div><div><p \
class="ydp4b316ddfyiv7486868869MsoNormal"><i><span \
style="font-size:12.0pt;color:black;"> \
ST_MakePoint(177,-48)</span></i><span \
style="font-size:12.0pt;font-family:sans-serif;color:black;"></span></p></div><div><p \
class="ydp4b316ddfyiv7486868869MsoNormal"><i><span \
style="font-size:12.0pt;color:black;"> \
\
),</span></i><span \
style="font-size:12.0pt;font-family:sans-serif;color:black;"></span></p></div><div><p \
class="ydp4b316ddfyiv7486868869MsoNormal"><i><span \
style="font-size:12.0pt;color:black;"> \
4326)); </span></i><span \
style="font-size:12.0pt;font-family:sans-serif;color:black;"></span></p></div><p \
class="ydp4b316ddfyiv7486868869MsoNormal"><span \
style="font-size:12.0pt;font-family:sans-serif;color:black;"> </span></p></div><div><p \
class="ydp4b316ddfyiv7486868869MsoNormal"><span \
style="font-size:12.0pt;font-family:sans-serif;color:black;"> \
</span></p></div><div><p class="ydp4b316ddfyiv7486868869MsoNormal"><span \
style="font-size:12.0pt;font-family:sans-serif;">I want to update the empty \
linestrings in one table (events) with slightly randomised versions of the linestring \
in the other (std_tow).</span></p></div><div><p \
class="ydp4b316ddfyiv7486868869MsoNormal"><span \
</div>
</div></body></html>
_______________________________________________
postgis-users mailing list
postgis-users@lists.osgeo.org
https://lists.osgeo.org/mailman/listinfo/postgis-users
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic