Subscribe to this thread
Home - General / All posts - Select image tiles within bounds
gjsa41 post(s)
#31-Oct-18 11:19

Have been using some of the functions in the forums to convert image pixels to either points or squares. See:

http://www.georeference.org/forum/t145329.10

http://www.georeference.org/forum/t144160.23

Would be great if these functions could be run on only some of the image tiles as defined by some boundary or rectangle (bounds of a vector layer, for example). I may have missed something in existing scripts, but I can't locate an extra bit of code for M9 that can restrain these functions spatially in real world coordinates, instead of X,Y values.

So, the code needs to select specific tiles within a min and max X,Y range by converting some bounding geometry into the same image X,Y coordinate system.

(The alternative to all this is just to run these processes on the entire image and then clip the result using the vector transform templates in M9. Which is fine, except that some of these images are continental scale, so converting the entire image and then removing all the unwanted shapes is too inefficient in processing time.)

adamw


8,204 post(s)
#01-Nov-18 09:04

Following from this post, incorporating the fix from Tim:

If the desired area is small enough, you can just cut it as a single tile:

--SQL9

VALUE @xmin INT32 = 1300;

VALUE @xmax INT32 = 1500;

VALUE @ymin INT32 = 100;

VALUE @ymax INT32 = 300;

 

DELETE FROM [german_alps_points];

 

INSERT INTO [german_alps_points] ([geom][value])

SELECT GeomMakePoint(VectorMakeX2(@xmin + [x] + 0.5, @ymin + [y] + 0.5)),

  [value]

FROM CALL TileToValues(TileCutRect([german_alps],

    VectorMakeX4(@xmin, @ymin, @xmax, @ymax)

  ));

If the desired area is big, you can request the tiles under it and cut them individually:

--SQL9

VALUE @xmin INT32 = 1300;

VALUE @xmax INT32 = 1500;

VALUE @ymin INT32 = 100;

VALUE @ymax INT32 = 300;

 

DELETE FROM [german_alps_points];

 

INSERT INTO [german_alps_points] ([geom][value])

SELECT GeomMakePoint(VectorMakeX2(

  ValueMax([tx]*128, @xmin) + [x] + 0.5,

  ValueMax([ty]*128, @ymin) + [y] + 0.5)), [value]

FROM (

  SELECT [x] AS [tx][y] AS [ty],

    SPLIT CALL TileToValues(TileCutRect([german_alps], VectorMakeX4(

      ValueMax(VectorValue([rect], 0), @xmin),

      ValueMax(VectorValue([rect], 1), @ymin),

      ValueMin(VectorValue([rect], 2), @xmax),

      ValueMin(VectorValue([rect], 3), @ymax)

    )))

  FROM CALL ValueSequenceTileXY(

    VectorMakeX4(@xmin, @ymin, @xmax, @ymax), VectorMakeX2(128, 128), false

  )

);

If you want to filter out invisible pixels, add WHERE [value] IS NOT NULL, etc.

See attached MXB.

Attachments:
make-points-restricted.mxb

gjsa41 post(s)
#04-Nov-18 22:04

I'm still searching for some code that will use a vector area to select the tiles in the make-points process.

This way, the process would only use tiles that touch the vector area.

Once the touching tiles have been converted, I can then intersect (standard overlay topology template) the rectangular make-points output with the vector area to get exactly those points within the area.

The code above doesn't allow the bounds of some vector area to set max-min X,Y values used to restrict the tiles.

tjhb

8,335 post(s)
#04-Nov-18 22:29

I think it would be great if you could post an image of how you ideally want the vector layer to constrain the raster layer.

How curved, rectangular, convex, convoluted.

gjsa41 post(s)
#04-Nov-18 23:43

I only want to select tiles as a way of reducing the overhead on any make points operation. It's not critical that I select exactly the pixels that intersect with the vector layer. That can be done precisely afterwards by overlaying topology with the points layer resulting from the converted tiles.

Effectively I'm looking for a rough "clip image by vector extent" function. This thread explains that raster<>vector clipping functions in 9 are yet to be implemented and goes on to suggest iteratively "guessing" the max,min X,Y values to constrain an image to the extent of a vector layer.

Until there are templates to intersect images with shapes, is it possible to improve the guessing process above in SQL 9 by computing the max,min X,Y values from some vector layer extent?

tjhb

8,335 post(s)
#05-Nov-18 00:40

There are lots of ways, of course.

But you should say exactly what you want, either with data or (at least) with a picture.

Otherwise you are effectively saying, "While I don't want to waste my own time, I am happy to waste yours." For my part, no thanks.

gjsa41 post(s)
#05-Nov-18 01:25

Ok, no trouble. I've tried to explain it in different ways but only getting your hackles up, lets leave it there. Thanks for repyling. Happy to waste my own time.

tjhb

8,335 post(s)
#05-Nov-18 03:51

Dilemma is: to have a quick go (half an hour, might work very well for a specific task), or to try to write a general solution (maybe invest a day). Really tricky without an example.

adamw


8,204 post(s)
#05-Nov-18 07:56

You mean how to set @xmin, @ymin, @xmax, @ymax automatically from coordinates of some geom?

Try this:

--SQL9

 

-- compose single vector area to get data for

VALUE @area GEOM = (SELECT GeomUnionAreas([geom]FROM [vector_area]);

 

-- convert area to image coordinates and compute its bounds in pixels

VALUE @area GEOM = CoordConvert(CALL CoordConverterMake(

  ComponentCoordSystem([german_alps]),

  ComponentCoordSystem([vector_area])), @area);

VALUE @rect FLOAT64X4 = GeomBoundsRect(@area);

VALUE @xmin INT32 = Floor(VectorValue(@rect, 0));

VALUE @ymin INT32 = Floor(VectorValue(@rect, 1));

VALUE @xmax INT32 = Ceil(VectorValue(@rect, 2));

VALUE @ymax INT32 = Ceil(VectorValue(@rect, 3));

 

-- rest same as make_points_restricted

 

DELETE FROM [german_alps_points];

 

INSERT INTO [german_alps_points] ([geom][value])

SELECT GeomMakePoint(VectorMakeX2(

  ValueMax([tx]*128, @xmin) + [x] + 0.5,

  ValueMax([ty]*128, @ymin) + [y] + 0.5)), [value]

FROM (

  SELECT [x] AS [tx][y] AS [ty],

    SPLIT CALL TileToValues(TileCutRect([german_alps], VectorMakeX4(

      ValueMax(VectorValue([rect], 0), @xmin),

      ValueMax(VectorValue([rect], 1), @ymin),

      ValueMin(VectorValue([rect], 2), @xmax),

      ValueMin(VectorValue([rect], 3), @ymax)

    )))

  FROM CALL ValueSequenceTileXY(

    VectorMakeX4(@xmin, @ymin, @xmax, @ymax), VectorMakeX2(128, 128), false

  )

);

See attached MXB.

Attachments:
make-points-restricted-by-area.mxb

gjsa41 post(s)
#06-Nov-18 11:44

That's perfect thanks. Apologies to @tjhb for my confusing and complicated explanation of the issue.

Manifold User Community Use Agreement Copyright (C) 2007-2017 Manifold Software Limited. All rights reserved.