Element capturing and C ++ implementation in GIS

Source: Internet
Author: User

This article was written as early as last year. However, because a part of my graduation thesis was directly referenced in this article at that time, I deleted the article for fear of re-checking. Here, upload the file and share it with you.

Element selection, also known as element capturing, plays an important role in CAD, computer graphics, and geographic information systems. For example, you need to determine which point, line, and face to select based on the mouse clicks on the screen. This is a common operation. This operation allows you to conveniently view attributes of elements and perform operations on elements.

The following describes the selection of different shape elements for points, lines, and surfaces.

Point: points are captured to calculate the distance between points. To speed up the search, you can set the current point as the center, A proper distance spreads around to form a square for search, and then the distance is calculated based on the search result set. However, the calculation distance will inevitably lead to the root operation, which will certainly lead to a longer computing time. There can be a distance absolute value on the direction of X and Y to replace the distance, as long as FABs (y2-y1) <EPS and FABS (x2-x1) <EPS meet the search conditions. In this way, point capturing is realized.

Line: Line capturing can be first understood as the calculation of the shortest distance between a point and a line. The distance between a point and a line segment can be first divided into the distance between the point and line segment, and then the minimum value of these distances is obtained. This looks good, but the efficiency is too low and the computing volume is large. It is not suitable for large-scale data search. Now let's first look at the distance from the line segment. Some people may say, you are stupid. Isn't that easy? Just find the distance between the point and the line? Sorry to tell you, it is a pity that this is not the definition. The general solution is as follows: first obtain the projection proj on the vector composed of the starting point of the outlet segment to the starting point and ending point of the vector online segment, and then compare the projection with the length of the Line Segment, less than 0, directly obtain the distance from the starting point of the line segment as the nearest distance. If 0 <proj <length (AB), the vertical distance is used as the shortest distance. If proj>
= Length (AB), the distance between this point and the end of the line segment is obtained as the shortest distance.

The Code is as follows:

Double point2segment (const ogrpoint & point, ogrpoint & pt0, ogrpoint & pt1)
{
Ogrpoint vecd (pt1.getx ()-pt0.getx (),
Pt1.gety ()-pt0.gety (); // vector of the Line Segment
Ogrpoint vecp (point. getx ()-pt0.getx (), point. Gety ()-pt0.gety (); // The vector from the point to the starting point of the Line Segment
Double valued = SQRT (vecd. getx () * vecd. getx () + vecd. Gety () * vecd. Gety ());
Double valuep = SQRT (vecp. getx () * vecp. getx () + vecp. Gety () * vecp. Gety ());
Double dotmultiplay = vecd. getx () * vecp. getx () + vecd. Gety () * vecp. Gety ();

Double T = dotmultiplay/valued; // projection of the calculated Vector

// If the start point of a line segment is close to the point
If (T <= 0)
{
Return valuep;
}

// If the end point of a line segment is close to the point
If (T> = valued)
{
Ogrpoint vecp (point. getx ()-pt1.getx (), point. Gety ()-pt1.gety ());
Return SQRT (vecp. getx () * vecp. getx () + vecp. Gety () * vecp. Gety ());
}

// Returns the vertical distance.
Return valuep-T * t/valued;
}

The second step is to find the minimum value from the point to all line segments. This time, you can find and then compare it. Most people may do this, but I want to say that programming is not just about implementing functions, but also optimizing algorithms and self-written code. Here, we can perform the following optimization: During the search process of each line segment, the minimum distance value of the last record is recorded. The current vertex can be the center point of the rectangle, the shortest distance of the above record spreads around to form a rectangle. This rectangle is a secure rectangle for the time being. If a line segment is within this rectangle or overlaps with this rectangle, distance calculation can be performed. If the conditions are not met, the next line segment is discarded. This saves a lot of unnecessary computing work.

The Code is as follows:

Double point2linestring (const ogrpoint & point, ogrlinestring * postring)
{
Double distance = 65535;
For (INT I = 0; I <postring-> getnumpoints ()-1; I ++)
{
Ogrpoint pt0, pt1;
Postring-> getpoint (I, & pt0 );
Postring-> getpoint (I + 1, & pt1 );

// This rectangle is used as a search tool.
Ogrenvelope envsearch;
Envsearch. Minx = point. getx ()-distance;
Envsearch. Maxx = point. getx () + distance;
Envsearch. miny = point. Gety ()-distance;
Envsearch. Maxy = point. Gety () + distance;
Ogrenvelope envsegment; // rectangle of the Line Segment
Envsegment. Minx = min (pt0.getx (), pt1.getx ());
Envsegment. Maxx = max (pt0.getx (), pt1.getx ());
Envsegment. miny = min (pt0.gety (), pt1.gety ());
Envsegment. Maxy = max (pt0.gety (), pt1.gety ());

// Calculate the distance only when the line segment is included or intersecting with the search rectangle
If (envsearch. Contains (envsegment) |
Envsearch. intersects (envsegment ))
{
Double Dist = point2segment (point, pt0, pt1 );
If (distance> = DIST)
{
Distance = DIST;
}
}
}

Return distance;
}

Step 3: search based on the created spatial index, find out the elements of the symbol condition, compare the distance one by one, and check whether the value is smaller than the threshold value. Convert the value to the screen distance before comparison.

Polygon (surface): see my other blog post (relationship between points and polygon (improved Shooting Method )).

We can discuss any better optimization solutions.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.