How to get all metes and bounds instead of just one? - python

I'm trying to pull all of the metes and bounds from a PDF document. Right now I have a code that reads the pdf and pulls in all the text. After it pulls in all the text I want it to pull out only the metes and bounds within the legal. The code works, however, it only pulls in one of them instead of all of them.
This is the code I run after extracting the text:
import pytesseract
from pdf2image import convert_from_path
import os
def extract_text_from_pdf(pdf_path, poppler_path, tesseract_path):
# set the path to the tesseract executable
pytesseract.pytesseract.tesseract_cmd = tesseract_path
# convert PDF to image
images = convert_from_path(pdf_path, poppler_path=poppler_path)
# loop through each page and extract text
extracted_text = ""
for i, image in enumerate(images):
# save the image temporarily
image_path = f'temp_image_{i}.png'
image.save(image_path)
# extract text from the image
text = pytesseract.image_to_string(image_path)
# append the extracted text
extracted_text += text
# remove the temporary image file
os.remove(image_path)
# extract the metes and bounds section
metes_and_bounds = find_metes_and_bounds(extracted_text)
return metes_and_bounds
pdf_path = r'C:\Users\user\Desktop\U0102639.pdf'
poppler_path = r'C:\Program Files (x86)\poppler-0.68.0\bin'
tesseract_path = r'C:\Program Files\Tesseract-OCR\tesseract.exe'
metes_and_bounds = extract_text_from_pdf(pdf_path, poppler_path, tesseract_path)
print(metes_and_bounds)
This is the output 00°12'55" W 658.37
Here is the full legal:
Commence at a 3/8" rebar marking the northwest corner of the Northeast
Quarter (NE1/4) of the Southwest Quarter (SW1/4) of Section 14,
Township 13 South, Range 5 East; and from thence run $ 00°12'55" W for
a distance of 658.37 feet to a capped rebar found (20125); thence run
S 89°45'44" E for a distance of 1284.98 feet to an axle found on the
northwest right of way of Lister Ferry Road (60' ROW); thence deflect
left and run northeasterly along said right of way a chord distance of
282.52 feet to a capped rebar found (20125); thence leaving said right of way, run N 73°54'04" W for a distance of 1432.68 feet, more or
less, to the point of beginning; SAVE AND EXCEPT the following portion
thereof: Commence at a 3/8" rebar marking the northwest corner of the
Northeast Quarter (NE1/4) of the Southwest Quarter (SW1/4) of Section
14, Township 13 South, Range 5 East; and from thence run § 00°12'55" W
for a distance of 658.37 feet to a capped rebar found (20125); thence
run S 89°45'44" E for a distance of 1284.98 feet to an axle found on
the northwest right of way of Lister Ferry Road (60! ROW), and which
point is the point of beginning of the parcel described herein; thence
from said point of beginning, deflect 180 and run N 89°45'54" W a
distance of 200 feet to a point; thence deflect right and run N
11°35'44" Wa distance of 75 feet to a point; thence deflect right and
run in a southeasterly the direction in a straight line to the point
of beginning of said excepted parcel.

It is not clear what your exact aim is but the best approach is probably to separate each Phrase; and filter for the best average output from OCR where several errors have been added. This is about as good as I can suggest, but as I don't know regex or Python you will need to apply as per their syntax
either ([N|S|§|$][^a-zA-Z]*[E|W])|(of\s\d+.*eet) or more visually grouped per below
([N|S|§|$][^a-zA-Z]*[E|W])(.*)(of\s\d+.*eet)|(of\s\d+.*eet)

Related

Triangulate location with Python having 3 anchors and 1 tag

I have 4 sensors: 3 anchors and 1 tag. The 3 anchors measure the distance the tag is located.
Anchor 1 is 30 cm to the left of anchor 2.
Anchor 3 is 30 cm from the center between anchor 1 and anchor 2.
The diameter of the distance of anchor 1 and anchor 2 is 530 cm (distance at which the tag is located). The diameter of the distance from anchor 3 is 600 cm (distance at which the tag is located).
There is a point that collides between all the diameters of the anchor and that is the position of the person.
I want to know in code:
How far away is the person (straight line from the center).
Whether the person is in front, back, left, or right.
Honestly, I can't think of a way to do it in real life and that's why I'm asking for help, I'm a bit lost. Who can help me, please?
# My sensor gives me this variable data, but, let's use these default values
# Distance where the person (tag) is
anchor_1 = 530
anchor_2 = 530
anchor_3 = 600
I found this library, but, I don't think it can help much since it uses GPS data, my sensors are not GPS: https://github.com/ricardojoserf/triangle-position
Firstly 530,530,600 cannot be the results of the 3 sensors, as they the 3 circles will never coincide. Changing that too 530,530,560.
Assuming your anchors are rounded of to integers, and considering the center of anchor_1 and anchor_2 as the origin of the cartesian plane, the following code will give you the rounded off coordinates of the tag
anchor_1 = 530
anchor_2 = 530
anchor_3 = 560
h_dist = 30
v_dist = 30
y = round(((anchor_1**2)-((((anchor_1**2) - (anchor_2**2) + (h_dist**2))/(2*h_dist))**2))**0.5)
x = round(((anchor_1**2) - (anchor_2**2) + (h_dist**2))/(2*h_dist))
if anchor_3 == y + v_dist:
y = -y
x = x - h_dist//2
print(x,y)

How to find out whether a point coordinate exists on a path between other two point coordinates?

I've created an application that scrapes data on house listings and calculates the distance to the nearest shop and train station. I've got the lat,lon coordinates for all the shops, listings and train stations and I currently use geopy.distance
import geopy.distance
distanceToShop = geopy.distance.distance(shopCoordinate, listingCoordinate).km
distanceToStation = geopy.distance.distance(stationCoordinate, listingCoordinate).km
These yield a value in kilometers between the two points. Then I filter out locations that are not close enough to a shop and trainstation. For train stations I tolerate a longer distance than for shops. Sometimes the shop is too far to be filtered in, but on the way to the station. In situations like this I would tolerate a longer distance to the shop, since it's on the way to the station.
In this case the shop is between the house and the stations. Station is at coordinate (40.651100, -73.949626). House is at coordinate (40.651401, -73.937987). Distance between house and station is 0.98 kilometers.
In the below scenario shop is at coordinate (40.650913, -73.948301) and distance from house to shop is 870 meters.
Acceptable distance from house to shop is 650 meters. However, if shop is on the way from the station a longer distance is acceptable. If I naively drop out houses because the closest shop is too far (870m > 650m) then this house would not qualify, but in this case the shop is on the way from the station (on the road home), so it should qualify.
Representation of problem on a map
A more robust solution would calculate an area between the two points (e.g. a square), and find out whether the shop is located within the square. This would allow for a more realistic result.
Representation of square drawn on map
How can I find out programatically if this is the case? Are there libraries that I could study?
EDIT: SOLVED - found out a way to calculate the bearing (degree angle between two coordinates) which can be manipulated and used to calculate other coordinates. By calculating the bearing I am able to offset it by +/- 90 degrees to create corners for both the target and destination coordinates. Then using another import (shapely) I drew a polygon from the coordinates and checked whether the shop existed in that matrix.
EDIT 2: Neater solution using geographiclib.geodesic with fewer imports:
import geopy.distance
from geographiclib.geodesic import Geodesic
from shapely.geometry import Point
from shapely.geometry.polygon import Polygon
def getAreaCorners(origin, target, distanceInMeters, angle):
geod = Geodesic.WGS84
bearing = geod.Inverse(origin[0], origin[1], target[0], target[1])['azi1']
rightBearing = bearing + angle
if rightBearing < 0: rightBearing += 360
leftBearing = bearing - angle
if leftBearing < 0: leftBearing += 360
og1 = geod.Direct(origin[0], origin[1], rightBearing, distanceInMeters)
og2 = geod.Direct(origin[0], origin[1], leftBearing, distanceInMeters)
og1 = (og1['lat2'], og1['lon2'])
og2 = (og2['lat2'], og2['lon2'])
tg1 = geod.Direct(target[0], target[1], rightBearing, distanceInMeters)
tg2 = geod.Direct(target[0], target[1], leftBearing, distanceInMeters)
tg1 = (tg1['lat2'], tg1['lon2'])
tg2 = (tg2['lat2'], tg2['lon2'])
return [og1, og2, tg2, tg1]
def isShopOnPath(areaCoordinateList, shopCoordinate):
polygon = Polygon(areaCoordinateList)
shopCoordinatePoint = Point(shopCoordinate)
return polygon.contains(shopCoordinatePoint)
origin = (40.650809, -73.949583)
target = (40.644661, -73.943108)
shopCoordinate = (40.650467, -73.948553)
distanceInMeters = 100
angle = 90
distanceToShop = round(geopy.distance.distance(shopCoordinate, target).km,2)
distanceToStation = round(geopy.distance.distance(origin, target).km,2)
print('House is {} km from station. Shop is {} km from house.'.format(distanceToStation, distanceToShop))
if distanceToShop >= 0.65:
if isShopOnPath(getAreaCorners(origin, target, distanceInMeters, angle), shopCoordinate):
print('Shop is too far, but on the way from the station.')
else:
print('Shop is too far and not on the way from the station')
else:
print('Shop is less than 650m from the house.')

ROS TurtleBot 2 laser scanner seem to scan the side

I'm new to ROS, and I have a mission to develop an algorithm that allows
the robot to move forward as long as he doesn't have an obstacle in front of
him, but it kept getting stuck in obstacles that I've put in front of him in the gazebo simulation.
When I checked it in depth, I figured that it seems that my robot scans to the sides instead of in front. And when I checked the specs for the scanner laser
it said that the angles of the scan should be maximum between -90 degrees to 90 degrees and preferably much less than that. So it seems that I can't complete my mission due to "hardware" problems but it seems strange to me.
Can anyone please help?
Here is my code:
#!/usr/bin/python
#
# stopper.py
#
# Created on:
# Author:
#
import rospy
import math
from geometry_msgs.msg import Twist
from sensor_msgs.msg import LaserScan
class Stopper(object):
def __init__(self, forward_speed):
self.forward_speed = forward_speed
self.min_scan_angle = -10/180*math.pi
self.max_scan_angle = 10 / 180 * math.pi
self.min_dist_from_obstacle = 0.5
self.keep_moving = True
self.command_pub = rospy.Publisher("/cmd_vel_mux/input/teleop", Twist, queue_size=10)
self.laser_subscriber = rospy.Subscriber("scan",LaserScan, self.scan_callback, queue_size=1)
def start_moving(self):
rate = rospy.Rate(10)
rospy.loginfo("Starting to move")
while not rospy.is_shutdown() and self.keep_moving:
self.move_forward()
rate.sleep()
def move_forward(self):
move_msg = Twist()
move_msg.linear.x = self.forward_speed
self.command_pub.publish(move_msg)
def scan_callback(self, scan_msg):
for dist in scan_msg.ranges:
if dist < self.min_dist_from_obstacle:
self.keep_moving = False
break
You should be able to select the angles you are interested in yourself. The -90 and +90 degrees are just the endpoints the laser scanner measures. So you get a dataset with a lot of distances in different angles. To detect obstacles in front of the robot you need to select a (or multiple) measurements in the middle of the dataset (my knowledge is rusty, I assume the ranges are sorted from -90° to 90° so 0° is in the middle of the array). So you may don't want to loop through all distances in msg.ranges but just a subset.
I found this tutorial that shows how to read out the data and access to the value from different angles.

Pyephem, define and plotting stars for different epochs

I'm trying to make a program that displays stars of my choice, from different locations on Earth and at different epochs. I've got it working so that I can display objects from ephem's database, such as Venus, but the stars I want to display aren't in the catalogue. How would I define the stars in Capricornus so they read to the program like any other star?
I've researched around and found articles similar to what I want:
The list of stars available:
https://github.com/brandon-rhodes/pyephem/blob/master/ephem/stars.py
Sample script plotting Big Dipper:http://nbviewer.ipython.org/github/brandon-rhodes/pyephem/blob/master/issues/github-issue-61.ipynb#
The code I'm using to generate observation site and desired objects:
#Define observer location
gatech = Observer()
gatech.lon = '-3.0' #Longitude positive in the East
gatech.lat = '+51.0' #Latitude positive in the North
gatech.elevation = 0
#Set date of observation and then prints Altitude and Azimuth of object
gatech.date = ((2000, 1, 1, 9, 30, 0)) #Year,month,day,hour,minute,second
v1 = Venus(gatech)
v1altrad = ('%.12f' % float(v1.alt))
v1azrad = ('%.12f' % float(v1.az -3.14159))
And inputting this into a matplotlib function produces the correct image.
As far as I know, I just need to figure out how to define the stars I want to see, as everything else appears to work. Any help plotting the stars of Capricorn would be greatly appreciated.
What you really want to do is to convert arbitrary equatorial coordinates to horizontal coordinates for a given location and time.
There are at least two options:
You can either create your own version of "stars.py", say "mystars.py" and
import that,
or do something like this
star = ephem.FixedBody(ra='21:00:00', dec='-20:00:00')
star.compute(gatech)
print(star.alt, star.az)

Cartesian projection issue in a FITS image through PyFITS / AstroPy

I've looked and looked for a solution to this problem and am turning up nothing.
I'm generating rectangular FITS images through matplotlib and subsequently applying WCS coordinates to them using AstroPy (or PyFITS). My images are in galactic latitude and longitude, so the header keywords appropriate for my maps should be GLON-CAR and GLAT-CAR (for Cartesian projection). I've looked at other maps that use this same map projection in SAO DS9 and the coordinates work great... the grid is perfectly orthogonal as it should be. The FITS standard projections can be found here.
But when I generate my maps, the coordinates are not at all Cartesian. Here's a side-by-side comparison of my map (left) and another reference map of roughly the same region (right). Both are listed GLON-CAR and GLAT-CAR in the FITS header, but mine is screwy when looked at in SAO DS9 (note that the coordinate grid is something SAO DS9 generates based on the data in the FITS header, or at least stored somewhere in the FITS file):
This is problematic, because the coordinate-assigning algorithm will assign incorrect coordinates to each pixel if the projection is wrong.
Has anyone encountered this, or know what could be the problem?
I've tried applying other projections (just to see how they perform in SAO DS9) and they come out fine... but my Cartesian and Mercator projections do not come out with the orthogonal grid like they should.
I can't believe this would be a bug in AstroPy, but I can't find any other cause... unless my arguments in the header are incorrectly formatted, but I still don't see how that could cause the problem I'm experiencing. Or would you recommend using something else? (I've looked at matplotlib basemap but have had some trouble getting that to work on my computer).
My header code is below:
from __future__ import division
import numpy as np
from astropy.io import fits as pyfits # or use 'import pyfits, same thing'
#(lots of code in between: defining variables and simple calculations...
#probably not relevant)
header['BSCALE'] = (1.00000, 'REAL = TAPE*BSCALE + BZERO')
header['BZERO'] = (0.0)
header['BUNIT'] = ('mag ', 'UNIT OF INTENSITY')
header['BLANK'] = (-100.00, 'BLANK VALUE')
header['CRVAL1'] = (glon_center, 'REF VALUE POINT DEGR') #FIRST COORDINATE OF THE CENTER
header['CRPIX1'] = (center_x+0.5, 'REF POINT PIXEL LOCATION') ## REFERENCE X PIXEL
header['CTYPE1'] = ('GLON-CAR', 'COORD TYPE : VALUE IS DEGR')
header['CDELT1'] = (-glon_length/x_length, 'COORD VALUE INCREMENT WITH COUNT DGR') ### degrees per pixel
header['CROTA1'] = (0, 'CCW ROTATION in DGR')
header['CRVAL2'] = (glat_center, 'REF VALUE POINT DEGR') #Y COORDINATE OF THE CENTER
header['CRPIX2'] = (center_y+0.5, 'REF POINT PIXEL LOCATION') #Y REFERENCE PIXEL
header['CTYPE2'] = ('GLAT-CAR', 'COORD TYPE: VALUE IS DEGR') # WAS CAR OR TAN
header['CDELT2'] = (glat_length/y_length, 'COORD VALUE INCREMENT WITH COUNT DGR') #degrees per pixel
header['CROTA2'] = (rotation, 'CCW ROTATION IN DEGR') #NEGATIVE ROTATES CCW around origin (bottom left).
header['DATAMIN'] = (data_min, 'Minimum data value in the file')
header['DATAMAX'] = (data_max, 'Maximum data value in the file')
header['TELESCOP'] = ("Produced from 2MASS")
pyfits.update(filename, map_data, header)
Thanks for any help you can provide.
In the modern definition of the -CAR projection (from Calabretta et al.), GLON-CAR/GLAT-CAR projection only produces a rectilinear grid if CRVAL2 is set to zero. If CRVAL2 is not zero, then the grid is curved (this should have nothing to do with Astropy). You can try and fix this by adjusting CRVAL2 and CRPIX2 so that CRVAL2 is zero. Does this help?
Just to clarify what I mean, try, after your code above, and before writing out the file:
header['CRPIX2'] -= header['CRVAL2'] / header['CDELT2']
header['CRVAL2'] = 0.
Any luck?
If you look at the header for the 'reference' file you looked at, you'll see that CRVAL2 is zero there. Just to be clear, there's nothing wrong with CRVAL2 being non-zero, but the grid is then no longer rectilinear.

Categories