Package: geocalc
GeoCalcGeoCalc is a Python library for geometric calculations, focusing on horizontal and vertical curves, angles, triangles, polygons, leveling, and geodesy in transportation engineering and surveying. The library provides various classes and functions for computing and setting out curves, angles, and more.FeaturesCompute various curve parameters for horizontal curves (Simple, Circular, and Spiral) and Vertical Curves. Calculate the Point of Intersection (PI), Point of Curvature (PC), and Point of Tangency (PT). Calculate chainages and convert between meters and chainage strings. Support for both metric and imperial unitsAngle computations and conversions, including degree-minute-second (DMS) and decimal degreesTriangle calculations including area, perimeter, and anglesPolygon calculations including area and perimeterLevelling calculations for elevation and height differencesGeodesy calculations for distance and bearingInstallationYou can install GeoCalc using pip:pipinstallgeocalcUsageHorizontal CurvesfromgeocalcimportHorizontalCurve,CircularCurves,SpiralCurves# Create a circular curvecurve=CircularCurve(radius=400,central_angle=24.533333)starting_chainage=4545.500interval=20print(curve)print("External:",curve.external_distance())print("Middle Ordinate:",curve.middle_ordinate())print("Long Chord:",curve.long_chord())Computing Stake Curve by Coordinatesinitial_x,initial_y,azimuth=5723.183,3728.947,326.672222pi,pc,pt,stake_curve_by_coordinates_table=curve.stake_curve_by_coordinates(interval=interval,initial_x=initial_x,initial_y=initial_y,azimuth=azimuth,PI=starting_chainage)print(pi,pc,pt)print("\nComputing Stake Curve by Coordinates:\n",stake_curve_by_coordinates_table)Create a spiral curvespiral_curve=SpiralCurves(radius=100,degree_of_curve=2)# Calculate curve parametersspiral_degree_of_curve=spiral_curve.spiral_degree_of_curve(Ls=20)Vertical CurvesfromgeocalcimportVerticalCurve# Create a vertical curvevertical_curve=VerticalCurve(PVI_elevation=100,grade_in=2,grade_out=-3,length=200)# Calculate curve parameterselevation_at_station=vertical_curve.elevation_at_station(50)Angles# Example usagefromgeocalcimportAngleangle_deg=Angle(45,'deg')print("DMS:",angle_deg.dms)print("Degrees:",angle_deg.deg)print("Radians:",angle_deg.rad)print("Grads:",angle_deg.grad)# An example with DMS dataangle_dms=Angle((30,45,0),'dms')print("DMS:",angle_dms.dms)print("Degrees:",angle_dms.deg)print("Radians:",angle_dms.rad)print("Grads:",angle_dms.grad)Example more usageangle_converter=Angle()# Degrees to radiansprint("Degrees to radians:",angle_converter.degrees_to_radians(45))# Radians to degreesprint("Radians to degrees:",angle_converter.radians_to_degrees(math.pi/4))# Degrees to gradsprint("Degrees to grads:",angle_converter.degrees_to_grads(45))# Grads to degreesprint("Grads to degrees:",angle_converter.grads_to_degrees(50))# Radians to gradsprint("Radians to grads:",angle_converter.radians_to_grads(math.pi/4))# Grads to radiansprint("Grads to radians:",angle_converter.grads_to_radians(50))# Degrees to DMSprint("Degrees to DMS:",angle_converter.degrees_to_dms(45.12345))# DMS to degreesprint("DMS to degrees:",angle_converter.dms_to_degrees(45,7,24.42))TriangleExample usagefromgeocalcimportTriangletriangle=Triangle(a=3,b=4,c=5,A=(0,0),B=(3,0))vertex_c1,vertex_c2=triangle.calculate_other_coordinates()print("Possible third vertex coordinates:",vertex_c1,vertex_c2)Example usagetriangle_area=Triangle()# Heron's formulaprint("Heron's formula:",triangle_area.heron_formula(3,4,5))# Trigonometric formulaprint("Trigonometric formula:",triangle_area.trigonometric_formula(3,4,90))# Base-height formulaprint("Base-height formula:",triangle_area.base_height_formula(3,4))# Coordinates formulaprint("Coordinates formula:",triangle_area.coordinates_formula(coords=((0,0),(3,0),(0,4))))Example usagetriangle=Triangle(3,4,5,angle_c=90)# Heron's formulaprint("Heron's formula:",triangle.heron())# Trigonometric formulaprint("Trigonometric formula:",triangle.trigonometric())PolygonfromgeocalcimportPolygon#Create a polygon with coordinatesvertices=[(1613.26,2418.11),(1806.71,2523.16),(1942.17,2366.84),(1901.89,2203.18),(1652.08,2259.26)]polygon=Polygon(vertices)print("Shoelace formula: ",polygon.shoelace())print("Triangulation: ",polygon.triangulation())print("Trapezoidal rule: ",polygon.trapezoidal())print("Monte Carlo method (10,000 points): ",polygon.monte_carlo(num_points=10000))print("Green's theorem: ",polygon.greens_theorem())print("\nCentroid: ",polygon.centroid())print("Moment of inertia: ",polygon.moment_of_inertia())print("\nAngle Between Side 1 and 2: ",polygon.angle_between_sides(0,1))print("Length of side 1: ",polygon.side_length_irregular(0))print("Length of side 2: ",polygon.side_length_irregular(1))print("\nIs Point(1806.71, 2523.16) inside: ",polygon.is_point_inside_polygon((1806.71,2400.16)))print("Is convex: ",polygon.is_convex())print("\nBounding box: ",polygon.bounding_box())print("\nOriginal: ",polygon.vertices)polygon.scale(2.5)print("\nScaled by 2.5: ",polygon.vertices)polygon.scale(1/2.5)print("\nUnScale by 1/2.5: ",polygon.vertices)polygon.translate(1.0,1.0)print("\nTranslated by (1.0, 1.0): ",polygon.vertices)print("\nNearest point to polygon: ",polygon.nearest_point_on_polygon((1920.17,2200.18)))print("\nConvexHull: ",polygon.convex_hull())Create a new regular polygonpolygon=Polygon(num_sides=5,side_length=4)print("\n\nArea: ",polygon.area_polygon())print("Perimeter: ",polygon.perimeter())print("Interior angle: ",polygon.interior_angle())print("Exterior angle: ",polygon.exterior_angle())perimeter=polygon.perimeter()area=polygon.area_polygon()circumradius=polygon.circumradius()inradius=polygon.inradius()# Create polygon and compute the length from other parameterspolygon=Polygon(num_sides=5)print("Side length from perimeter:",polygon.get_side_length(perimeter=perimeter))print("Side length from area:",polygon.get_side_length(area=area))print("Side length from circumradius:",polygon.get_side_length(circumradius=circumradius))print("Side length from inradius:",polygon.get_side_length(inradius=inradius))LevellingfromgeocalcimportLevellingstarting_tbm=100.000closing_tbm=98.050data=[('A',1.751,None,None),('B',None,0.540,None),('C',0.300,None,2.100),('D',None,1.100,None),('E',None,1.260,None),('F',1.500,None,2.300),('G',None,None,1.100)]leveling=Levelling(starting_tbm=starting_tbm,closing_tbm=closing_tbm,k=5)# Add dataforstation,bs,is_,fsindata:leveling.add_data(station,bs,is_,fs)# Calculate reduced levels using HPC algorithmleveling.compute_heights(method="hpc")print(f"\n\nNumber of instrument station ={leveling.numberSTN}\n")# Perform arithmetic checksarithmetic_results=leveling.arithmetic_check()print("\nArithmetic Checks:")print(f"Sum of BS ={arithmetic_results['sum_bs']:.3f}")print(f"Sum of FS ={arithmetic_results['sum_fs']:.3f}")print(f"First RL ={arithmetic_results['first_rl']:.3f}")print(f"Last RL ={arithmetic_results['last_rl']:.3f}")print(f"Sum of BS - Sum of FS ={arithmetic_results['bs_minus_fs']:.4f}")print(f"Last RL - First RL ={arithmetic_results['last_rl_minus_first_rl']:.4f}")ifarithmetic_results['is_arithmetic_check_passed']:print("Arithmetic Checks are OK.")else:diff=arithmetic_results['bs_minus_fs']-arithmetic_results['last_rl_minus_first_rl']print(f"Arithmetic Checks failed with{diff:.4f}differences")print(f"\nAllowable misclose ={leveling.allowable_misclose():.4f}mm")print(f"Misclose ={leveling.misclose:.4f}m ({leveling.misclose*1000:.4f}mm)"ifleveling.miscloseisnotNoneelseNone)print(f"Leveling Status:{'Work is accepted'ifleveling.is_work_accepted()else'Work is not accepted'}.\n")print(f"Correction ={round(leveling.correction,5)ifleveling.correctionisnotNoneelseNone}")print(f"Correction per station ={round(leveling.adjustment_per_station,5)ifleveling.adjustment_per_stationisnotNoneelseNone}\n")#Print HPC tableprint("HPC:",leveling.get_dataFrame())Calculate reduced levels using Rise & Fall algorithmleveling.compute_heights(method="rise_fall")print(leveling.misclose)# Print the miscloseprint(leveling.adjustedRLs)# Prints the adjusted RLs#Include the rounding decimal pointsprint("Rise & Fall:\n",leveling.get_dataFrame(roundDigits=5))GeodesyfromgeocalcimportGeodesy# Calculate distance and bearing between two pointspoint_a=(12.4924,41.8902)# Colosseum, Romepoint_b=(2.2945,48.8582)# Eiffel Tower, Parisdistance,bearing=Geodesy.distance_and_bearing(point_a,point_b)geodesy=Geodesy()# Haversine distancedistance1=geodesy.haversine_distance(40.689247,-74.044502,48.858844,2.294351)print(f"Haversine distance:{distance1}meters")# Vincenty distancedistance2=geodesy.vincenty_distance(40.689247,-74.044502,48.858844,2.294351)print(f"Vincenty distance:{distance2}meters")# Area of geodesic polygonpolygon_coordinates=[(30,0),(30,10),(40,10),(40,0)]area=geodesy.area_of_geodesic_polygon(polygon_coordinates)print(f"Area of geodesic polygon:{area}square meters")ContributingIf you'd like to contribute to GeoCalc, please open an issue or submit a pull request on the GitHub repository.LicenseThis project is licensed under the MIT License. See the LICENSE file for details.