[GRASS-SVN] r68831 - grass-addons/grass7/vector/v.civil
svn_grass at osgeo.org
svn_grass at osgeo.org
Fri Jul 1 15:30:22 PDT 2016
Author: jfc
Date: 2016-07-01 15:30:22 -0700 (Fri, 01 Jul 2016)
New Revision: 68831
Added:
grass-addons/grass7/vector/v.civil/img1.png
grass-addons/grass7/vector/v.civil/img2.png
grass-addons/grass7/vector/v.civil/img2_1.png
grass-addons/grass7/vector/v.civil/img2_2.png
grass-addons/grass7/vector/v.civil/img3.png
grass-addons/grass7/vector/v.civil/img3_2.png
grass-addons/grass7/vector/v.civil/img4.png
grass-addons/grass7/vector/v.civil/img4_1.png
grass-addons/grass7/vector/v.civil/img4_2.png
grass-addons/grass7/vector/v.civil/img4_3.png
grass-addons/grass7/vector/v.civil/img5.png
grass-addons/grass7/vector/v.civil/img6.png
grass-addons/grass7/vector/v.civil/img6_1.png
grass-addons/grass7/vector/v.civil/img7.png
grass-addons/grass7/vector/v.civil/img8.png
grass-addons/grass7/vector/v.civil/img8_1.png
grass-addons/grass7/vector/v.civil/img8_2.png
grass-addons/grass7/vector/v.civil/img_a_plan.png
grass-addons/grass7/vector/v.civil/img_a_tooladdrow.png
grass-addons/grass7/vector/v.civil/img_a_topotools_1.png
grass-addons/grass7/vector/v.civil/img_a_vcivilroad_7.png
grass-addons/grass7/vector/v.civil/img_a_vert.png
grass-addons/grass7/vector/v.civil/img_tables1.png
grass-addons/grass7/vector/v.civil/img_tables2.png
grass-addons/grass7/vector/v.civil/img_tables2_2.png
grass-addons/grass7/vector/v.civil/img_tables2_3.png
grass-addons/grass7/vector/v.civil/img_tables3.png
grass-addons/grass7/vector/v.civil/img_tables3_1.png
grass-addons/grass7/vector/v.civil/img_tables3_2.png
grass-addons/grass7/vector/v.civil/img_tables4_1.png
grass-addons/grass7/vector/v.civil/img_tables4_2.png
grass-addons/grass7/vector/v.civil/img_tables5_1.png
grass-addons/grass7/vector/v.civil/img_tables6_1.png
grass-addons/grass7/vector/v.civil/img_tables7_1.png
grass-addons/grass7/vector/v.civil/road_base.py
grass-addons/grass7/vector/v.civil/road_crosstools.py
grass-addons/grass7/vector/v.civil/road_displ.py
grass-addons/grass7/vector/v.civil/road_marks.py
grass-addons/grass7/vector/v.civil/road_plant.py
grass-addons/grass7/vector/v.civil/road_profiles.py
grass-addons/grass7/vector/v.civil/road_road.py
grass-addons/grass7/vector/v.civil/road_tables.py
grass-addons/grass7/vector/v.civil/road_terr.py
grass-addons/grass7/vector/v.civil/road_topotools.py
grass-addons/grass7/vector/v.civil/road_trans.py
grass-addons/grass7/vector/v.civil/road_vertical.py
grass-addons/grass7/vector/v.civil/v.road.html
grass-addons/grass7/vector/v.civil/v.road.py
Modified:
grass-addons/grass7/vector/v.civil/Makefile
Log:
v.civil.road: Rewritten using pygrass to v.road
Modified: grass-addons/grass7/vector/v.civil/Makefile
===================================================================
--- grass-addons/grass7/vector/v.civil/Makefile 2016-07-01 22:16:30 UTC (rev 68830)
+++ grass-addons/grass7/vector/v.civil/Makefile 2016-07-01 22:30:22 UTC (rev 68831)
@@ -1,13 +1,14 @@
+# fix this relative to include/
+# or use absolute path to the GRASS source code
+
MODULE_TOPDIR = ../..
+PGM = v.road
-SUBDIRS = \
- v.civil.river \
- v.civil.road \
- v.civil.tools \
- v.civil.topo
+ETCFILES = road_road road_base road_plant road_vertical road_displ \
+ road_terr road_profiles road_trans road_tables road_marks \
+ road_crosstools road_topotools
-include $(MODULE_TOPDIR)/include/Make/Dir.make
+include $(MODULE_TOPDIR)/include/Make/Script.make
+include $(MODULE_TOPDIR)/include/Make/Python.make
-default: parsubdirs
-
-install: installsubdirs
+default: script
Added: grass-addons/grass7/vector/v.civil/img1.png
===================================================================
(Binary files differ)
Property changes on: grass-addons/grass7/vector/v.civil/img1.png
___________________________________________________________________
Added: svn:mime-type
+ image/png
Added: grass-addons/grass7/vector/v.civil/img2.png
===================================================================
(Binary files differ)
Property changes on: grass-addons/grass7/vector/v.civil/img2.png
___________________________________________________________________
Added: svn:mime-type
+ image/png
Added: grass-addons/grass7/vector/v.civil/img2_1.png
===================================================================
(Binary files differ)
Property changes on: grass-addons/grass7/vector/v.civil/img2_1.png
___________________________________________________________________
Added: svn:mime-type
+ image/png
Added: grass-addons/grass7/vector/v.civil/img2_2.png
===================================================================
(Binary files differ)
Property changes on: grass-addons/grass7/vector/v.civil/img2_2.png
___________________________________________________________________
Added: svn:mime-type
+ image/png
Added: grass-addons/grass7/vector/v.civil/img3.png
===================================================================
(Binary files differ)
Property changes on: grass-addons/grass7/vector/v.civil/img3.png
___________________________________________________________________
Added: svn:mime-type
+ image/png
Added: grass-addons/grass7/vector/v.civil/img3_2.png
===================================================================
(Binary files differ)
Property changes on: grass-addons/grass7/vector/v.civil/img3_2.png
___________________________________________________________________
Added: svn:mime-type
+ image/png
Added: grass-addons/grass7/vector/v.civil/img4.png
===================================================================
(Binary files differ)
Property changes on: grass-addons/grass7/vector/v.civil/img4.png
___________________________________________________________________
Added: svn:mime-type
+ image/png
Added: grass-addons/grass7/vector/v.civil/img4_1.png
===================================================================
(Binary files differ)
Property changes on: grass-addons/grass7/vector/v.civil/img4_1.png
___________________________________________________________________
Added: svn:mime-type
+ image/png
Added: grass-addons/grass7/vector/v.civil/img4_2.png
===================================================================
(Binary files differ)
Property changes on: grass-addons/grass7/vector/v.civil/img4_2.png
___________________________________________________________________
Added: svn:mime-type
+ image/png
Added: grass-addons/grass7/vector/v.civil/img4_3.png
===================================================================
(Binary files differ)
Property changes on: grass-addons/grass7/vector/v.civil/img4_3.png
___________________________________________________________________
Added: svn:mime-type
+ image/png
Added: grass-addons/grass7/vector/v.civil/img5.png
===================================================================
(Binary files differ)
Property changes on: grass-addons/grass7/vector/v.civil/img5.png
___________________________________________________________________
Added: svn:mime-type
+ image/png
Added: grass-addons/grass7/vector/v.civil/img6.png
===================================================================
(Binary files differ)
Property changes on: grass-addons/grass7/vector/v.civil/img6.png
___________________________________________________________________
Added: svn:mime-type
+ image/png
Added: grass-addons/grass7/vector/v.civil/img6_1.png
===================================================================
(Binary files differ)
Property changes on: grass-addons/grass7/vector/v.civil/img6_1.png
___________________________________________________________________
Added: svn:mime-type
+ image/png
Added: grass-addons/grass7/vector/v.civil/img7.png
===================================================================
(Binary files differ)
Property changes on: grass-addons/grass7/vector/v.civil/img7.png
___________________________________________________________________
Added: svn:mime-type
+ image/png
Added: grass-addons/grass7/vector/v.civil/img8.png
===================================================================
(Binary files differ)
Property changes on: grass-addons/grass7/vector/v.civil/img8.png
___________________________________________________________________
Added: svn:mime-type
+ image/png
Added: grass-addons/grass7/vector/v.civil/img8_1.png
===================================================================
(Binary files differ)
Property changes on: grass-addons/grass7/vector/v.civil/img8_1.png
___________________________________________________________________
Added: svn:mime-type
+ image/png
Added: grass-addons/grass7/vector/v.civil/img8_2.png
===================================================================
(Binary files differ)
Property changes on: grass-addons/grass7/vector/v.civil/img8_2.png
___________________________________________________________________
Added: svn:mime-type
+ image/png
Added: grass-addons/grass7/vector/v.civil/img_a_plan.png
===================================================================
(Binary files differ)
Property changes on: grass-addons/grass7/vector/v.civil/img_a_plan.png
___________________________________________________________________
Added: svn:mime-type
+ image/png
Added: grass-addons/grass7/vector/v.civil/img_a_tooladdrow.png
===================================================================
(Binary files differ)
Property changes on: grass-addons/grass7/vector/v.civil/img_a_tooladdrow.png
___________________________________________________________________
Added: svn:mime-type
+ image/png
Added: grass-addons/grass7/vector/v.civil/img_a_topotools_1.png
===================================================================
(Binary files differ)
Property changes on: grass-addons/grass7/vector/v.civil/img_a_topotools_1.png
___________________________________________________________________
Added: svn:mime-type
+ image/png
Added: grass-addons/grass7/vector/v.civil/img_a_vcivilroad_7.png
===================================================================
(Binary files differ)
Property changes on: grass-addons/grass7/vector/v.civil/img_a_vcivilroad_7.png
___________________________________________________________________
Added: svn:mime-type
+ image/png
Added: grass-addons/grass7/vector/v.civil/img_a_vert.png
===================================================================
(Binary files differ)
Property changes on: grass-addons/grass7/vector/v.civil/img_a_vert.png
___________________________________________________________________
Added: svn:mime-type
+ image/png
Added: grass-addons/grass7/vector/v.civil/img_tables1.png
===================================================================
(Binary files differ)
Property changes on: grass-addons/grass7/vector/v.civil/img_tables1.png
___________________________________________________________________
Added: svn:mime-type
+ image/png
Added: grass-addons/grass7/vector/v.civil/img_tables2.png
===================================================================
(Binary files differ)
Property changes on: grass-addons/grass7/vector/v.civil/img_tables2.png
___________________________________________________________________
Added: svn:mime-type
+ image/png
Added: grass-addons/grass7/vector/v.civil/img_tables2_2.png
===================================================================
(Binary files differ)
Property changes on: grass-addons/grass7/vector/v.civil/img_tables2_2.png
___________________________________________________________________
Added: svn:mime-type
+ image/png
Added: grass-addons/grass7/vector/v.civil/img_tables2_3.png
===================================================================
(Binary files differ)
Property changes on: grass-addons/grass7/vector/v.civil/img_tables2_3.png
___________________________________________________________________
Added: svn:mime-type
+ image/png
Added: grass-addons/grass7/vector/v.civil/img_tables3.png
===================================================================
(Binary files differ)
Property changes on: grass-addons/grass7/vector/v.civil/img_tables3.png
___________________________________________________________________
Added: svn:mime-type
+ image/png
Added: grass-addons/grass7/vector/v.civil/img_tables3_1.png
===================================================================
(Binary files differ)
Property changes on: grass-addons/grass7/vector/v.civil/img_tables3_1.png
___________________________________________________________________
Added: svn:mime-type
+ image/png
Added: grass-addons/grass7/vector/v.civil/img_tables3_2.png
===================================================================
(Binary files differ)
Property changes on: grass-addons/grass7/vector/v.civil/img_tables3_2.png
___________________________________________________________________
Added: svn:mime-type
+ image/png
Added: grass-addons/grass7/vector/v.civil/img_tables4_1.png
===================================================================
(Binary files differ)
Property changes on: grass-addons/grass7/vector/v.civil/img_tables4_1.png
___________________________________________________________________
Added: svn:mime-type
+ image/png
Added: grass-addons/grass7/vector/v.civil/img_tables4_2.png
===================================================================
(Binary files differ)
Property changes on: grass-addons/grass7/vector/v.civil/img_tables4_2.png
___________________________________________________________________
Added: svn:mime-type
+ image/png
Added: grass-addons/grass7/vector/v.civil/img_tables5_1.png
===================================================================
(Binary files differ)
Property changes on: grass-addons/grass7/vector/v.civil/img_tables5_1.png
___________________________________________________________________
Added: svn:mime-type
+ image/png
Added: grass-addons/grass7/vector/v.civil/img_tables6_1.png
===================================================================
(Binary files differ)
Property changes on: grass-addons/grass7/vector/v.civil/img_tables6_1.png
___________________________________________________________________
Added: svn:mime-type
+ image/png
Added: grass-addons/grass7/vector/v.civil/img_tables7_1.png
===================================================================
(Binary files differ)
Property changes on: grass-addons/grass7/vector/v.civil/img_tables7_1.png
___________________________________________________________________
Added: svn:mime-type
+ image/png
Added: grass-addons/grass7/vector/v.civil/road_base.py
===================================================================
--- grass-addons/grass7/vector/v.civil/road_base.py (rev 0)
+++ grass-addons/grass7/vector/v.civil/road_base.py 2016-07-01 22:30:22 UTC (rev 68831)
@@ -0,0 +1,1343 @@
+# -*- coding: utf-8 -*-
+"""
+Created on Thu Jul 31 12:02:25 2014
+
+ at author: meskal
+"""
+
+#
+# import pygrass modules
+#
+import math
+import re
+# from grass.pygrass.vector import VectorTopo
+from grass.pygrass.vector import VectorTopo
+from grass.pygrass.vector.geometry import Point
+from grass.pygrass.vector.geometry import Line
+
+
+def azimut(p_ini=None, p_end=None):
+ """Return Azimut of two point (x1,y1) (x2,y2), Rad from North
+ to clockwise
+
+ >>> azimut(Point(0,0), Point(10,10))
+ 0.7853981633974483
+ """
+ if p_ini.x > p_end.x and p_ini.y == p_end.y:
+ azi = 3 * math.pi / 2
+ elif p_ini.x < p_end.x and p_ini.y == p_end.y:
+ azi = math.pi / 2
+ elif p_ini.x == p_end.x and p_ini.y > p_end.y:
+ azi = math.pi
+ elif p_ini.x == p_end.x and p_ini.y < p_end.y:
+ azi = 2 * math.pi
+ elif p_ini.x == p_end.x and p_ini.y == p_end.y:
+ azi = 0
+ else:
+ azi = math.atan((p_end.x - p_ini.x) / (p_end.y - p_ini.y))
+ # if x1> x2 and y1 == y2: az = az + pi # az>0 -> az > 0
+ if p_ini.x < p_end.x and p_ini.y > p_end.y:
+ azi = azi + math.pi # az<0 -> az > 100
+ elif p_ini.x > p_end.x and p_ini.y > p_end.y:
+ azi = azi + math.pi # az>0 -> az > 200
+ elif p_ini.x > p_end.x and p_ini.y < p_end.y:
+ azi = azi + 2 * math.pi # az<0 -> az > 300
+ return azi
+
+
+# def fix_azimuth(azi):
+# """ Return
+# """
+# if azi > 2 * math.pi:
+# return azi - 2 * math.pi
+# else:
+# return azi + 2 * math.pi
+
+
+def aprox_coord(leng, tau):
+ """Return coord (x1,y1) of a clothoid given the angle Tau and length
+ ::
+ >>> aprox_coord(10, 5)
+ [-50, -50]
+ """
+ n_iter = 10
+ c_x = 0
+ c_y = 0
+ for n_i in range(n_iter):
+ c_x += (((-1) ** n_i * tau ** (2 * n_i)) /
+ ((4 * n_i + 1) * math.factorial(2 * n_i)))
+ c_y += (((-1) ** n_i * tau ** (2 * n_i + 1)) /
+ ((4 * n_i + 3) * math.factorial(2 * n_i + 1)))
+ c_x = c_x * leng
+ c_y = c_y * leng
+ return [c_x, c_y]
+
+
+def aprox_coord2(radio, tau):
+ """Return coord (x1,y1) of a clothoid given the angle Tau and Radio
+ ::
+ >>> aprox_coord(100, 50)
+ [-1411567899002100L, -3476091295999800L]
+ """
+ n_iter = 10
+ c_x = 0
+ c_y = 0
+ for n_i in range(n_iter):
+ c_x += (((-1) ** n_i * (2 * tau ** (2 * n_i + 1) /
+ ((4 * n_i + 1) * math.factorial(2 * n_i)))) -
+ ((-1) ** n_i * (tau ** (2 * n_i + 1) /
+ math.factorial(2 * n_i + 1))))
+
+ c_y += (((-1) ** n_i * (2 * tau ** (2 * n_i + 2) /
+ ((4 * n_i + 3) * math.factorial(2 * n_i + 1)))) +
+ ((-1) ** n_i * (tau ** (2 * n_i) / math.factorial(2 * n_i))))
+
+ c_x = c_x * radio
+ c_y = c_y * radio - radio
+ return [c_x, c_y]
+
+
+def cloth_local(radio, a_clot):
+ """Return clothoid parameters in local coord
+ ::
+ >>> cloth_local(40,20)
+ {'tau': 0, 'x_e': 10, 'leng': 10, 'x_o': 10.0, 'y_o': 0.0, 'y_e': 0}
+ """
+ if radio == 0:
+ leng, tau = 0, 0
+ else:
+ leng = a_clot ** 2 / abs(radio)
+ tau = leng / (2 * radio)
+ x_e, y_e = aprox_coord(leng, tau)
+ x_o = x_e - radio * math.sin(tau)
+ y_o = y_e + radio * math.cos(tau) - radio
+
+ return {'x_o': x_o, 'y_o': y_o, 'tau': tau, 'leng': leng, 'x_e': x_e,
+ 'y_e': y_e}
+
+
+def clotoide_get_a(radio, yo_ent, sobreancho, izq):
+ """Return param A of a clothoid in a curve with widening
+ """
+ inc = math.pi / 200
+ tau = 0.0001 * math.pi / 200
+ y_o = aprox_coord2(abs(radio), tau)[1]
+ if (izq and radio > 0) or (izq == 0 and radio < 0):
+ sobreancho = sobreancho
+ elif (izq and radio < 0) or (izq == 0 and radio > 0):
+ sobreancho = sobreancho * (-1)
+
+ # Comprobar que el sobreancho sea mayor que el retranqueo
+ while abs(y_o - (yo_ent - sobreancho)) > 0.0001:
+
+ y_o = aprox_coord2(abs(radio), tau)[1]
+ if y_o > yo_ent - sobreancho:
+ tau = tau - inc
+ inc = inc / 10
+ else:
+ tau = tau + inc
+
+ leng = tau * 2 * abs(radio)
+ return math.sqrt(leng * abs(radio))
+
+
+def bisecc(r_pnt, align):
+ """Return cutoff roadpoint of a straight, given by a roadpoint with its
+ azimuth, and a road object defined by the funct function
+ """
+ recta2 = r_pnt.normal(math.pi)
+ len_a = -0.00001
+ len_b = align.length()
+ eq_a = align.funct(len_a, recta2)
+ eq_b = align.funct(len_b, recta2)
+
+ if round(eq_a[0], 5) * round(eq_b[0], 5) > 0:
+ return None
+
+ len_c = (len_a + len_b) / 2.0
+ while (len_b - len_a) / 2.0 > 0.00001:
+ eq_c = align.funct(len_c, recta2)
+ eq_a = align.funct(len_a, recta2)
+ if eq_c[0] == 0:
+ continue
+ elif eq_a[0] * eq_c[0] <= 0:
+ len_b = len_c
+ else:
+ len_a = len_c
+ len_c = (len_a + len_b) / 2.0
+
+ return RoadPoint(Point(eq_c[1], eq_c[2], 0), len_c, r_pnt.azi, '')
+
+
+def format_pk(funcion_f):
+ """Return the pk format 10+000.001 of a funtion
+ """
+ def funcion_r(*arg):
+ """Return
+ """
+ ipk = funcion_f(*arg)
+ ipk = round(ipk, 4)
+ if str(ipk).find(".") == -1:
+ integer = str(ipk)
+ decimal = "0"
+ else:
+ integer, decimal = str(ipk).split(".")
+ integer = re.sub(r"\B(?=(?:\d{3})+$)", "+", "{:0>4}".format(integer))
+ return integer + "." + decimal
+ return funcion_r
+
+
+def write_objs(allrectas, radio):
+ """
+ """
+ new2 = VectorTopo('AAAAA__' + str(int(radio)))
+ # cols = [(u'cat', 'INTEGER PRIMARY KEY'),
+ # (u'elev', 'INTEGER')]
+
+ new2.open('w')
+ for obj in allrectas:
+ new2.write(obj)
+ # new2.table.conn.commit()
+ new2.close()
+
+
+# =============================================
+# ROAD POINT
+# =============================================
+
+class RoadPoint(Point, object):
+ """RoadPoint object, is a Point with pk and azimuth, and others params
+ >>> r_pnt = RoadPoint(Point(1,1,0), 0, 0)
+ """
+ def __init__(self, point=None, npk=None, azi=None, p_type=None):
+ """ Return
+ """
+ super(RoadPoint, self).__init__(point.x, point.y, point.z)
+
+ self.x = point.x
+ self.y = point.y
+ self.z = point.z
+ self.point2d = Point(self.x, self.y)
+
+ self.npk = npk
+ self.azi = azi
+ self.p_type = p_type
+ self.align = ''
+ self.incli = 0
+
+ self.v_param = 0
+ self.v_type = 'none'
+
+ self.terr = 0
+ self.terr_type = 'none'
+
+ self.dist_displ = 0
+ self.acum_pk = 0
+
+ if self.z is None:
+ self.z = 0
+
+ def __repr__(self):
+ return ("RoadPoint(" + str(self.x) + ", " + str(self.y) + ", " +
+ str(self.z) + ", " +
+ str(self.npk) + ", " + str(self.azi) + ", " +
+ str(self.p_type) + ", " + str(self.align) + ", " +
+ str(self.v_param) + ", " + str(self.v_type) + ", " +
+ str(self.terr) + ", " + str(self.terr_type) + ", " +
+ str(self.dist_displ) + ")")
+
+ def get_wkt(self):
+ """Return a "well know text" (WKT) geometry string. ::
+
+ >>> pnt = Point(10, 100)
+ >>> pnt.get_wkt()
+ 'POINT(10.000000 100.000000)'
+ """
+ return ("ROADPOINT(" + str(self.x) + ", " + str(self.y) + ", " +
+ str(self.z) + ", " +
+ str(self.npk) + ", " + str(self.azi) + ", " +
+ str(self.p_type) + ", " + str(self.align) + ", " +
+ str(self.v_param) + ", " + str(self.v_type) + ", " +
+ str(self.terr) + ", " + str(self.terr_type) + ", " +
+ str(self.dist_displ) + ")")
+
+ def get_info(self):
+ """Return point pk
+ """
+ sal = 'ROADPOINT( \n'
+ sal += ' Point(' + str(self.x) + ", " + str(self.y) + ", " + \
+ str(self.z) + ')\n'
+ sal += ' pk: ' + str(self.npk) + '\n'
+ sal += ' azimuth: ' + str(self.azi * 200 / math.pi) + '\n'
+ sal += ' p_type: ' + str(self.p_type) + '\n'
+ sal += ' align: ' + str(self.align) + '\n'
+ sal += ' v_param: ' + str(self.v_param) + '\n'
+ sal += ' v_type: ' + str(self.v_type) + '\n'
+ sal += ' z_terr: ' + str(self.terr) + '\n'
+ sal += ' terr_type: ' + str(self.terr_type) + '\n'
+ sal += ' dist displ: ' + str(self.dist_displ) + '\n)'
+
+ return sal
+
+ @format_pk
+ def get_pk(self):
+ """Return point pk
+ """
+ return float(self.npk)
+
+ def get_azi(self):
+ """Return azimuth of roadpoint in gon
+ >>> r_pnt = RoadPoint(Point(1,1,0), 0, 0.7853981633974483)
+ >>> r_pnt.get_azi()
+ 50.0
+ """
+ return round(self.azi * 200 / math.pi, 4)
+
+ def azimuth(self, pnt2):
+ """Return azimuth of this roadpoint with another one
+ >>> r_pnt = RoadPoint(Point(1,1,0), 0, 0)
+ >>> r_pnt2 = RoadPoint(Point(2,2,0), 0, 0)
+ >>> r_pnt.azimuth(r_pnt2)
+ 0.7853981633974483
+ """
+ return azimut(self, pnt2)
+
+ def distance2(self, pnt2):
+ """Return point pk
+ """
+ return math.sqrt((pnt2.x - self.x) ** 2 + (pnt2.y - self.y) ** 2)
+
+ def slope(self, pnt2):
+ """Return the slope between this point and the given one
+ """
+ # leng = Point.distance(pnt2)
+ leng = math.sqrt((pnt2.x - self.x) ** 2 + (pnt2.y - self.y) ** 2)
+ if leng == 0:
+ return 0
+ else:
+ return (pnt2.z - self.z) / leng
+
+ def slope2(self, pnt2):
+ """Return the slope between this point and the given one
+ """
+ if self.npk == pnt2.npk:
+ return 0
+ else:
+ return (pnt2.z - self.z) / (pnt2.npk - self.npk)
+
+ def get_straight(self, dist=1):
+ """ Return
+ """
+ pto_2 = self.project(dist, self.azi)
+ return Straight(self, pto_2)
+
+ def project(self, dist, azi, sig=1):
+ """ Return
+ """
+ return RoadPoint(Point(self.x + sig * dist * math.sin(azi),
+ self.y + sig * dist * math.cos(azi)),
+ self.npk, azi, '')
+
+ def parallel(self, dist, g90):
+ """ Return
+ """
+ return RoadPoint(Point(self.x + dist * math.sin(self.azi + g90),
+ self.y + dist * math.cos(self.azi + g90)),
+ self.npk, self.azi, self.p_type)
+
+ def normal(self, g90):
+ """ Return
+ """
+ return Straight(self.point2d, None, self.azi + g90, 20)
+
+
+# =============================================
+# ROAD LINE
+# =============================================
+
+class RoadLine(object):
+ """Class to manage list of roadpoints
+ """
+ def __init__(self, list_r_pnts, attrs=None, name=None):
+ """ Return
+ """
+# super(RoadLine, self).__init__(list_r_pnts)
+# if isinstance(list_r_pnts[0], list):
+# self.list_r_pnts = list_r_pnts
+# else:
+# self.list_r_pnts = [list_r_pnts]
+
+ self.r_pnts = list_r_pnts
+ self.attrs = attrs
+ self.name = name
+# self.pnts_char = pnts_char
+
+ def __getitem__(self, index):
+ return self.r_pnts[index]
+
+ def __setitem__(self, index, value):
+ self.r_pnts[index] = value
+
+ def __delitem__(self, index):
+ del self.r_pnts[index]
+
+ def __len__(self):
+ return len(self.r_pnts)
+
+ def __repr__(self):
+ return str(self.r_pnts)
+
+ def length(self):
+ """ Return
+ """
+ return len(self.r_pnts)
+
+ def is_in(self, r_pnt):
+ """ Return
+ """
+ if r_pnt.npk in [pnt.npk for pnt in self.r_pnts]:
+ return True
+ else:
+ return False
+
+ def insert(self, r_pnt):
+ """Insert a roadpoint with pk like index
+ """
+# if not self.is_in(r_pnt):
+ for i, pnt in enumerate(self.r_pnts[:-1]):
+ if pnt.npk < r_pnt.npk < self.r_pnts[i + 1].npk:
+ self.r_pnts.insert(i + 1, r_pnt)
+
+# def get_segments(self, charline):
+# """Return
+# """
+
+ def get_by_pk(self, npk):
+ """Return the roadpoint with npk
+ """
+ for pnt in self.r_pnts:
+ if pnt is not None:
+ if pnt.npk == npk:
+ return pnt
+
+ def get_pnts_attrs(self):
+ """Return all roadpoints and their attributes
+ """
+ list_pnts = []
+ list_attrs = []
+ for r_pnt in self.r_pnts:
+ if r_pnt is not None:
+ list_pnts.append(r_pnt)
+ list_attrs.append([r_pnt.npk, self.name, r_pnt.azi,
+ r_pnt.p_type, r_pnt.align, r_pnt.v_param,
+ r_pnt.v_type, float(r_pnt.terr),
+ r_pnt.terr_type, r_pnt.dist_displ,
+ r_pnt.x, r_pnt.y, r_pnt.z, ''])
+ return list_pnts, list_attrs
+
+ def get_line_attrs(self, set_leng=None):
+ """Return Line or list of Lines, split if some roadpoint of the
+ roadline is None, and attributes
+ """
+ list_lines = [[]]
+ list_attrs = []
+ lista_lineas = []
+ for r_pnt in self.r_pnts:
+ if r_pnt is not None:
+ list_lines[-1].append(r_pnt)
+ elif list_lines[-1] != []:
+ list_lines.append([])
+ for i, lin in enumerate(list_lines):
+ if len(lin) != 0:
+ lista_lineas.append(Line(lin))
+ if set_leng:
+ self.attrs[set_leng] = round(lista_lineas[-1].length(), 6)
+ list_attrs.append(self.attrs)
+ return lista_lineas, list_attrs
+
+# def get_segm_attrs(self):
+# """Return
+# """
+# list_lines = []
+# list_attrs = []
+# for i, pnt_char in enumerate(self.pnts_char[1:]):
+# list_lines.append([self.pnts_char[i - 1]])
+# for r_pnt in self.r_pnts:
+# if r_pnt is not None:
+# if round(self.pnts_char[i - 1].npk, 6) < r_pnt.npk < \
+# pnt_char.npk:
+# list_lines[-1].append(r_pnt)
+# list_lines[-1].append(pnt_char)
+#
+# list_attrs.append([pnt_char.npk, pnt_char.p_type])
+#
+# return list_lines, list_attrs
+
+
+# def get_ras(self, r_line):
+# """Return
+# """
+# line = []
+# for r_pnt in r_line:
+# line.append(Point(r_pnt.npk + self.zero_x,
+# (r_pnt.z - self.min_elev) * self.scale +
+# self.zero_y))
+# return Line(line)
+#
+# def get_terr(self, r_line):
+# """Return
+# """
+# line = []
+# for r_pnt in r_line:
+# line.append(Point(r_pnt.npk + self.zero_x,
+# (r_pnt.terr - self.min_elev) * self.scale +
+# self.zero_y))
+# return Line(line)
+
+ def get_area(self, pnts_line2):
+ """Return a closed polyline with this roadline and the reverse of the
+ given roadline
+ """
+ list_lines = []
+ pnts_line1 = self.r_pnts
+ line1, line2 = [[]], [[]]
+ for i in range(len(pnts_line1)):
+ if pnts_line1[i] is None or pnts_line2[i] is None:
+ if line1[-1] != [] and line2[-1] != []:
+ line1.append([])
+ line2.append([])
+ else:
+ line1[-1].append(pnts_line1[i])
+ line2[-1].append(pnts_line2[i])
+
+ line1 = [lin for lin in line1 if lin != []]
+ line2 = [lin for lin in line2 if lin != []]
+
+ for i in range(len(line1)):
+
+ line2[i] = line2[i][::-1]
+ line2[i].append(line1[i][0])
+ line1[i].extend(line2[i])
+
+ line = Line(line1[i])
+ list_lines.append(line)
+
+ return list_lines
+
+
+# =============================================
+# ROAD OBJ
+# =============================================
+
+class RoadObj(object):
+ """Road object, base of straight, curve, clothoid and parallel
+ """
+ def __init__(self, leng_obj):
+ """ Return
+ """
+ self.leng_obj = leng_obj
+ self.leng_accum = 0
+
+ self.pts_rest = 0
+ self.pts_accum = 0
+
+ def param(self):
+ """Return string with length of the object
+ """
+ return 'L=' + str(round(self.leng_obj, 4))
+
+ @format_pk
+ def get_leng_accum(self):
+ """Return the length accum
+ """
+ return self.leng_accum
+
+ @format_pk
+ def get_leng_accum2(self):
+ """Return the length accum and length of this
+ """
+ return self.leng_accum + self.leng_obj
+
+ def is_in(self, r_pnt):
+ """
+ """
+ if self.leng_accum <= r_pnt.npk < self.leng_accum + self.leng_obj:
+ return True
+ else:
+ return False
+
+ def grassrgb(self):
+ """Return the default rgb color for each object
+ """
+ if isinstance(self, Straight):
+ return '0:0:255'
+ elif isinstance(self, Curve):
+ return '0:255:0'
+ elif isinstance(self, Clothoid):
+ return '255:0:0'
+ else:
+ return '255:255:255'
+
+ def get_roadpoint(self, start):
+ """Return a roadpoint found by pk
+ """
+ if start == -1:
+ start = self.leng_obj
+ self.pts_accum = start
+ r_pnt = self.get_roadpnts(start, start, 1)[0]
+ r_pnt.npk = self.leng_accum + start
+ if start == 0:
+ # r_pnt.p_type = self.pto_ini()
+ r_pnt.p_type = self.__class__.__name__ + '_in'
+ elif start == self.leng_obj:
+ # r_pnt.p_type = self.pto_end()
+ r_pnt.p_type = self.__class__.__name__ + '_out'
+ return [r_pnt]
+
+# def pto_ini(self):
+# """ Return
+# """
+# if isinstance(self, Straight):
+# return 'Straight_in'
+# elif isinstance(self, Curve):
+# return 'Curve_tan_in'
+# elif isinstance(self, Clothoid):
+# return 'Clothoid_tan_in'
+# else:
+# return 'No_name'
+#
+# def pto_end(self):
+# """ Return
+# """
+# if isinstance(self, Straight):
+# return 'Straight_end'
+# elif isinstance(self, Curve):
+# return 'Curve_tan_out'
+# elif isinstance(self, Clothoid):
+# return 'Clothoid_tan_out'
+# else:
+# return 'No_name'
+
+# def get_line(self, start, end, interv):
+# """ Return
+# """
+# pnts = self.get_roadpnts(start, end, interv)
+# lastpnt = self.get_roadpoint(-1)[0]
+# if lastpnt not in pnts:
+# pnts.append(lastpnt)
+# return Line(pnts)
+
+
+# =============================================
+# STRAIGHT
+# =============================================
+
+class Straight(RoadObj, object):
+ """Object straight, line with two points or point azimuth and leng
+ ::
+ >>> line = Straight(Point(0,0,0), Point(10,10,0), 0, 0)
+ >>> line.length()
+ 14.142135623730951
+ """
+ def __init__(self, pstart=None, pend=None, azi=None, leng=None):
+ """ Return
+ """
+ self.pstart = pstart
+ self.pend = pend
+ self.azi = azi
+ self.leng = leng
+
+# self.pts_rest = 0
+# self.pts_accum = 0
+
+ if self.azi and self.leng:
+ self.pend = Point(self.pstart.x + self.leng * math.sin(self.azi),
+ self.pstart.y + self.leng * math.cos(self.azi))
+
+ super(Straight, self).__init__(self.length())
+
+ def __str__(self):
+ if not self.pstart.z:
+ self.pstart.z = 0.0
+ return self.get_wkt()
+
+ def __repr__(self):
+ if not self.pstart.z:
+ self.pstart.z = 0.0
+ return ("Straight(" + str(self.pstart.x) + ", " + str(self.pstart.y) +
+ ", " + str(self.pstart.z) + ", " + str(self.length()) + ", " +
+ str(self.azimuth()) + ", " + str(self.pend.x) + ", " +
+ str(self.pend.y) + ")")
+
+ def get_wkt(self):
+ """Return a "well know text" (WKT) geometry string. ::
+ ::
+ >>> pnt = Point(10, 100)
+ >>> pnt.get_wkt()
+ 'POINT(10.000000 100.000000)'
+ """
+ return ("STRAIGHT(" + str(self.pstart.x) + ", " + str(self.pstart.y) +
+ ", " + str(self.pstart.z) + ", " + str(self.length()) + ", " +
+ str(self.azimuth()) + ", " + str(self.pend.x) + ", " +
+ str(self.pend.y) + ")")
+
+ def get_line(self):
+ """Return length of the straight
+ """
+ return Line([self.pstart, self.pend])
+
+ def length(self):
+ """Return length of the straight
+ """
+ return self.pstart.distance(self.pend)
+
+ def get_roadpnts(self, start, end, interv):
+ """Return list of axis points of a straight
+ ::
+ >>> line = Straight(Point(0,0,0), Point(10,10,0), 0, 0)
+ >>> line.get_roadpnts(3,7,1) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
+ [RoadPoint(2.12132034356, 2.12132034356, 0.0, 0, 0.785398163397,
+ ...
+ """
+ accum = self.pts_accum
+ if end == -1:
+ end = self.length()
+
+ azi = self.azimuth()
+ list_pts = []
+ while start <= end:
+ pnt = Point(self.pstart.x + start * math.sin(azi),
+ self.pstart.y + start * math.cos(azi), self.pstart.z)
+
+ list_pts.append(RoadPoint(pnt, accum, round(azi, 6), 'Line'))
+ accum += interv
+ start += interv
+
+ self.pts_rest = end - (start - interv)
+ self.pts_accum = accum - interv
+ return list_pts
+
+ def azimuth(self):
+ """Return azimut of the straight
+ ::
+ >>> line = Straight(Point(0,0,0), Point(10,10,0), 0, 0)
+ >>> line.azimuth()
+ 0.7853981633974483
+ """
+ return azimut(self.pstart, self.pend)
+
+ def slope(self):
+ """Return slope of the straight
+ ::
+ >>> line = Straight(Point(0,0,0), Point(10,10,10), 0, 0)
+ >>> line.slope()
+ 1.0
+ """
+ return (self.pend.z - self.pstart.z) / (self.pend.x - self.pstart.x)
+
+ def angle(self, recta2):
+ """Return angle between two straights
+ ::
+ >>> line = Straight(Point(0,0,0), Point(10,10,10), 0, 0)
+ >>> line2 = Straight(Point(30,0,0), Point(20,10,10), 0, 0)
+ >>> line.angle(line2) * 200 / math.pi
+ 100.0
+ """
+ az_ent = azimut(self.pstart, self.pend)
+ az_sal = azimut(recta2.pstart, recta2.pend)
+ a_w = abs(azimut(self.pstart, self.pend) -
+ azimut(recta2.pstart, recta2.pend))
+ if((self.pstart.x <= self.pend.x and self.pstart.y <= self.pend.y) or
+ (self.pstart.x <= self.pend.x and self.pstart.y >= self.pend.y)):
+ if az_ent < az_sal and az_ent + math.pi < az_sal:
+ a_w = 2 * math.pi - abs(az_ent - az_sal)
+
+ if((self.pstart.x >= self.pend.x and self.pstart.y >= self.pend.y) or
+ (self.pstart.x >= self.pend.x and self.pstart.y <= self.pend.y)):
+ # "3er o 4to cuadrante"
+ if az_ent > az_sal and az_ent - math.pi > az_sal:
+ a_w = 2 * math.pi - abs(az_ent - az_sal)
+ return a_w
+
+ def cutoff(self, recta2):
+ """Return the cutoff point between this straight an a given one.
+ ::
+ >>> line = Straight(Point(0,0,0), Point(10,10,10), 0, 0)
+ >>> line2 = Straight(Point(30,0,0), Point(20,10,10), 0, 0)
+ >>> line.cutoff(line2)
+ RoadPoint(15.0, 15.0, 0.0, 21.2132034356, 0, , , 0, none, 0, none, 0)
+ """
+ if self.pstart.x == self.pend.x:
+ m_2 = (recta2.pend.y - recta2.pstart.y) / \
+ (recta2.pend.x - recta2.pstart.x)
+ coord_x = self.pstart.x
+ coord_y = recta2.pstart.y + m_2 * (self.pstart.x - recta2.pstart.x)
+ elif recta2.pstart.x == recta2.pend.x:
+ m_1 = (self.pend.y - self.pstart.y) / (self.pend.x - self.pstart.x)
+ coord_x = recta2.pstart.x
+ coord_y = self.pstart.y + m_1 * (recta2.pstart.x - self.pstart.x)
+ else:
+ m_1 = (self.pend.y - self.pstart.y) / (self.pend.x - self.pstart.x)
+ m_2 = (recta2.pend.y - recta2.pstart.y) / \
+ (recta2.pend.x - recta2.pstart.x)
+ coord_x = (m_1 * self.pstart.x - m_2 * recta2.pstart.x -
+ self.pstart.y + recta2.pstart.y) / (m_1 - m_2)
+ coord_y = m_1 * (coord_x - self.pstart.x) + self.pstart.y
+
+ return RoadPoint(Point(coord_x, coord_y),
+ self.pstart.distance(Point(coord_x, coord_y)),
+ self.azi, '')
+
+ def funct(self, leng, recta2):
+ """Funtion for use with bisecc
+ """
+ x_1 = self.pstart.x + leng * math.sin(self.azimuth())
+ y_1 = self.pstart.y + leng * math.cos(self.azimuth())
+ eq1 = y_1 - (recta2.pstart.y - math.tan(recta2.azimuth()) *
+ (x_1 - recta2.pstart.x))
+ return [eq1, x_1, y_1]
+
+ def find_cutoff(self, r_pnt):
+ """Return the cutoff between this straight and other, given a r_pnt
+ with its azimuth.
+ >>> line = Straight(Point(0,0,0), Point(20,20,10), 0, 0)
+ >>> r_pnt = RoadPoint(Point(30,0,0), 0, line.azimuth(), 0)
+ >>> line.find_cutoff(r_pnt) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
+ RoadPoint(14.9999997412, 14.9999997412, 0.0, 21.2132039637,
+ ...
+ """
+ r_pnt_d = bisecc(r_pnt, self)
+ if r_pnt_d is not None:
+ r_pnt_d.p_type = 'Line'
+ return r_pnt_d
+
+ def distance(self, pnt):
+ """Return distace from a point to this straight
+ >>> line = Straight(Point(0,0,0), Point(20,20,10), 0, 0)
+ >>> line.distance(Point(10,0,0))
+ 7.071067811865475
+ """
+ if self.pstart.x == self.pend.x:
+ slope = 0
+ else:
+ slope = (self.pend.x - self.pstart.x) / \
+ (self.pend.y - self.pstart.y)
+ rest = self.pstart.y + slope * self.pstart.x
+ return (slope * pnt.x + pnt.y - rest) / math.sqrt(slope ** 2 + 1)
+
+ def parallel(self, dist, radio):
+ """Return a parallel straight with a given distance and side given by
+ the sing of radio.
+ >>> line = Straight(Point(0,0,0), Point(20,20,10), 0, 0)
+ >>> line.parallel(10, -1) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
+ Straight(-7.07106781187, 7.07106781187, 0.0, 28.2842712475,
+ ...
+ """
+ if radio > 0:
+ g90 = math.pi / 2
+ else:
+ g90 = -math.pi / 2
+
+ x_1 = self.pstart.x + dist * math.sin(self.azimuth() + g90)
+ y_1 = self.pstart.y + dist * math.cos(self.azimuth() + g90)
+
+ x_2 = self.pend.x + dist * math.sin(self.azimuth() + g90)
+ y_2 = self.pend.y + dist * math.cos(self.azimuth() + g90)
+
+ return Straight(Point(x_1, y_1), Point(x_2, y_2))
+
+
+# =============================================
+# CURVE
+# =============================================
+
+class Curve(RoadObj, object):
+ """Object Curve, curve with radio, angle, initial azimuth and center
+ ::
+ >>> r_pnt = RoadPoint(Point(50,50,0), 0, 0, 0)
+ >>> curve = Curve(10.0, 1.5707963268, 0.7853981633974483, r_pnt)
+ >>> curve.length()
+ 15.707963268
+ """
+ def __init__(self, radio=0, alpha=0, az_ini=0, p_center=None):
+
+ self.radio = radio
+ self.alpha = alpha
+ self.az_ini = az_ini
+
+ self.p_center = p_center
+
+ self.pts_rest = 0
+ self.pts_accum = 0
+
+ if self.radio > 0:
+ self.az_fin = self.az_ini + self.alpha
+ else:
+ self.az_fin = self.az_ini - self.alpha
+
+ if self.az_fin > 2 * math.pi:
+ self.az_fin = self.az_fin - 2 * math.pi
+ elif self.az_fin < 0:
+ self.az_fin = self.az_fin + 2 * math.pi
+
+ super(Curve, self).__init__(self.length())
+
+ def __str__(self):
+ return self.get_wkt()
+
+ def __repr__(self):
+
+ return ("Curve(" + str(self.radio) + ", " + str(self.alpha) + ", " +
+ str(self.p_center.x) + ", " + str(self.p_center.y) + ", " +
+ str(self.az_ini) + ", " + str(self.az_fin) + ", " +
+ str(self.length()) + ", " + str(self.pnt_ar()) + ", " +
+ str(self.pnt_ra()) + ", " + ")")
+
+ def get_wkt(self):
+ """Return a "well know text" (WKT) geometry string. ::
+
+ >>> pnt = Point(10, 100)
+ >>> pnt.get_wkt()
+ 'POINT(10.000000 100.000000)'
+ """
+ return ("CURVE(" + str(self.radio) + ", " + str(self.alpha) + ", " +
+ str(self.p_center.x) + ", " + str(self.p_center.y) + ", " +
+ str(self.az_ini) + ", " + str(self.az_fin) + ", " +
+ str(self.length()) + ", " + str(self.pnt_ar()) + ", " +
+ str(self.pnt_ra()) + ", " + ")")
+
+ def param(self):
+ """Return a string with the radio of the curve
+ """
+ return 'R=' + str(self.radio)
+
+ def length(self):
+ """Return length of the curve
+ """
+ return abs(self.radio) * self.alpha
+
+ def get_roadpnts(self, start, end, interv):
+ """ Return list of points of the curve, and set length of last point
+ to the end and accumulated length
+ ::
+ >>> r_pnt = RoadPoint(Point(50,50,0), 0, 0, 0)
+ >>> curve = Curve(10.0, 1.5707963268, 0.7853981633974483, r_pnt)
+ >>> curve.get_roadpnts(0, -1, 1.0) # doctest: +ELLIPSIS \
+ +NORMALIZE_WHITESPACE
+ [RoadPoint(57.0710678119, 57.0710678119, 0.0, 0,
+ ...
+ """
+ accum = self.pts_accum
+ az_ini = self.az_ini
+ if end == -1:
+ end = self.length()
+ list_pts = []
+ interv = abs(float(interv) / float(self.radio))
+
+ az_ini = az_ini + start / self.radio
+ az_fin = az_ini + (end - start) / self.radio
+
+ inc = az_ini
+ if self.radio > 0:
+
+ while inc <= az_fin:
+ pnt_1 = self.p_center.project(self.radio, inc)
+ az1 = (inc + math.pi / 2)
+ inc += interv
+
+ if az1 > 2 * math.pi:
+ az1 = az1 - 2 * math.pi
+
+ list_pts.append(RoadPoint(pnt_1, accum, round(az1, 6), 'Curve'))
+ accum += interv * abs(self.radio)
+ rest = (az_fin - (inc - interv)) * abs(self.radio)
+
+ elif self.radio < 0:
+
+ while inc >= az_fin:
+ pnt_1 = self.p_center.project(self.radio, inc, -1)
+ az1 = (inc - math.pi / 2)
+ inc -= interv
+
+ if az1 < 0:
+ az1 = az1 + 2 * math.pi
+
+ list_pts.append(RoadPoint(pnt_1, accum, round(az1, 6), 'Curve'))
+ accum += interv * abs(self.radio)
+ rest = ((inc + interv) - az_fin) * abs(self.radio)
+
+ self.pts_rest = rest
+ self.pts_accum = accum - interv * abs(self.radio)
+ return list_pts
+
+ def distance(self, pnt):
+ """Return distance from a point to the curve
+ ::
+ >>> r_pnt = RoadPoint(Point(50,50,0), 0, 1.5707963268, 0)
+ >>> curve = Curve(10.0, 1.5707963268, 0.7853981633974483, r_pnt)
+ >>> curve.distance(Point(0,0))
+ 60.710678118654755
+ """
+ line = Straight(self.p_center, pnt)
+ return line.length() - self.radio
+
+ def pnt_ar(self):
+ """Return the first point of the curve
+ """
+ return self.p_center.project(abs(self.radio), self.az_ini)
+
+ def pnt_ra(self):
+ """Return the last point of the curve
+ """
+ return self.p_center.project(abs(self.radio), self.az_fin)
+
+ def cutoff(self, recta2):
+ """Return the cutoff between this curve and a straight
+ """
+ dist = recta2.distance(self.p_center)
+ if dist == 0:
+ pnt_1 = self.p_center.project(self.radio, recta2.azimuth())
+ else:
+ phi = math.acos(dist / self.radio)
+ pnt_1 = self.p_center.project(self.radio, recta2.azimuth() +
+ math.pi / 2 + phi)
+ return pnt_1
+
+ def funct(self, leng, recta2):
+ """Funtion for use with bisecc
+ """
+ if self.radio > 0:
+ if self.az_ini > self.az_fin:
+ self.az_ini = self.az_ini - 2 * math.pi
+ x_1 = self.p_center.x + self.radio * \
+ math.sin(self.az_ini + leng / abs(self.radio))
+ y_1 = self.p_center.y + self.radio * \
+ math.cos(self.az_ini + leng / abs(self.radio))
+ elif self.radio < 0:
+ if self.az_ini < self.az_fin:
+ self.az_fin = self.az_fin - 2 * math.pi
+ x_1 = self.p_center.x - self.radio * \
+ math.sin(self.az_ini - leng / abs(self.radio))
+ y_1 = self.p_center.y - self.radio * \
+ math.cos(self.az_ini - leng / abs(self.radio))
+
+ eq1 = y_1 - (recta2.pstart.y - math.tan(recta2.azimuth()) *
+ (x_1 - recta2.pstart.x))
+ return [eq1, x_1, y_1]
+
+ def find_cutoff(self, r_pnt):
+ """Return the cutoff between this curve and a straight, given by r_pnt
+ with its azimuth.
+ """
+ r_pnt_d = bisecc(r_pnt, self)
+ if r_pnt_d is not None:
+ r_pnt_d.p_type = 'Curve_'
+ return r_pnt_d
+
+
+# =============================================
+# CLOTHOID
+# =============================================
+
+class Clothoid(RoadObj, object):
+ """Object Clothoid, with param A, radio, initial azimuth, in or out,
+ and center of the curve. Other_local coord in local of other clothoid
+ ::
+ """
+ def __init__(self, a_clot=0, radio=0, azi=0, inout='', other_local=None,
+ p_center=None):
+
+ self.radio = radio
+ self.a_clot = a_clot
+ self.other_local = other_local
+ self.azi = azi
+ self.inout = inout
+ self.p_center = p_center
+
+ self.pts_rest = 0
+ self.pts_accum = 0
+
+ if self.radio > 0:
+ self.g90 = math.pi / 2
+ else:
+ self.g90 = -math.pi / 2
+
+ if self.other_local:
+ self.leng_rest = self.other_local['leng']
+ else:
+ self.leng_rest = 0
+
+ self.pnt_r = None
+ self.pnt_d = None
+ self.pnt_p = None
+
+ self.local = cloth_local(self.radio, self.a_clot)
+
+ if self.inout == 'in':
+
+ if self.a_clot <= 0:
+ self.pnt_r = self._pnt_ar()
+ self.pnt_d = self.pnt_r
+ self.pnt_p = self.pnt_r
+ else:
+ self.pnt_d = self._pnt_ad()
+ self.pnt_r = self._pnt_ar()
+ self.pnt_p = self.pnt_d
+
+ if self.other_local:
+ self.leng_rest = self.other_local['leng']
+ self.pnt_p = self._pnt_adp()
+ else:
+ if self.a_clot <= 0:
+ self.pnt_r = self._pnt_ra()
+ self.pnt_d = self.pnt_r
+ self.pnt_p = self.pnt_r
+ else:
+ self.pnt_d = self._pnt_da()
+ self.pnt_r = self._pnt_ra()
+ self.pnt_p = self.pnt_d
+
+ if self.other_local:
+ self.leng_rest = self.other_local['leng']
+ self.pnt_p = self._pnt_dap()
+
+ super(Clothoid, self).__init__(self.length())
+
+ def __str__(self):
+ return self.get_wkt()
+
+ def __repr__(self):
+ return ("Clothoid(" + str(self.a_clot) + ", " + str(self.azi) +
+ ", " + str(self.pnt_d) + ", " +
+ str(self.pnt_r.x) + ", " + str(self.pnt_r.y) + ", " +
+ str(self.length()) + ", " +
+ str(self.radio) + ", " + str(self.leng_rest) + ", " +
+ str(self.pnt_p.x) + ", " + str(self.pnt_p.y) + ", " +
+ self.inout + ")")
+
+ def get_wkt(self):
+ """Return a "well know text" (WKT) geometry string. ::
+
+ >>> pnt = Point(10, 100)
+ >>> pnt.get_wkt()
+ 'POINT(10.000000 100.000000)'
+ """
+ return ("CLOTHOID(" + str(self.a_clot) + ", " + str(self.azi) +
+ ", " + str(self.pnt_d) + ", " + str(self.pnt_r) + ", " +
+ str(self.length()) + ", " +
+ str(self.radio) + ", " + str(self.leng_rest) + ", " +
+ str(self.pnt_p) + ", " + self.inout + ")")
+
+ def param(self):
+ """Return a string with the parameter A of the clothoid
+ """
+ return 'A=' + str(self.a_clot)
+
+ def length(self):
+ """Return length of the clothoid
+ """
+ if self.a_clot <= 0:
+ return 0
+ elif self.other_local:
+ return self.other_local['leng'] - self.leng_rest
+ else:
+ return self.local['leng']
+
+ def get_roadpnts(self, start, end, interv):
+ """Return list of points of the curve, and set length of last point
+ to the end and accumulated length
+ ::
+ >>> r_pnt = RoadPoint(Point(50,50,0), 0, 0, 0)
+ >>> cloth = Clothoid(20, 40, 0, 'in', None, r_pnt)
+ >>> cloth.get_roadpnts(0, -1, 1) # doctest: +ELLIPSIS \
+ +NORMALIZE_WHITESPACE
+ [RoadPoint(10.0, 40.0000001, 0.0, 0,
+ ...
+ """
+ if end == -1:
+ end = self.length()
+
+ if self.inout == 'in':
+ return self._get_pts_clot_in(start, end, interv)
+ elif self.inout == 'out':
+ return self._get_pts_clot_out(start, end, interv)
+
+ def _get_pts_clot_in(self, start, end, interv):
+ """ Return list of axis points of clothoid in, and set the rest to
+ the end of the clothoid and accum length
+ """
+ accum = self.pts_accum
+ list_pts = []
+ while start <= end:
+ if start == 0:
+ start = 0.0000001
+ rad_clo = self.a_clot ** 2 / start
+ tau_clo = start / (2 * rad_clo)
+ x_o, y_o = aprox_coord(start, tau_clo)
+ x_1, y_1 = self.cloth_global(x_o, y_o)
+ azi1 = self.pnt_azimuth(tau_clo)
+ list_pts.append(RoadPoint(Point(x_1, y_1, 0), accum,
+ round(azi1, 6), 'Clot_in'))
+ accum += interv
+ start = start + interv
+
+ self.pts_rest = end - (start - interv)
+ self.pts_accum = accum - interv
+ return list_pts
+
+ def _get_pts_clot_out(self, start, end, interv):
+ """ Return list of axis points of clothoid out, and set the rest to
+ the end of the clothoid and accum length
+ """
+ accum = self.pts_accum
+ list_pts = []
+ start2 = self.length() - end
+ end2 = self.length() - start
+
+ while start2 <= end2:
+ if end2 == 0:
+ end2 = 0.0000001
+
+ rad_clo = self.a_clot ** 2 / end2
+ tau_clo = end2 / (2 * rad_clo)
+ x_o, y_o = aprox_coord((end2), tau_clo)
+ x_1, y_1 = self.cloth_global(x_o, y_o)
+ azi1 = self.pnt_azimuth(tau_clo)
+ list_pts.append(RoadPoint(Point(x_1, y_1, 0), accum,
+ round(azi1, 6), 'Clot_out'))
+ accum += interv
+ end2 = end2 - interv
+
+ self.pts_rest = start2 + (end2 + interv)
+ self.pts_accum = accum - interv
+
+ return list_pts
+
+ def _pnt_ar(self):
+ """Return the first point of the clothoid in
+ """
+ return self.p_center.project(abs(self.radio),
+ self.azi - self.g90 + self.local['tau'])
+
+ def _pnt_ad(self):
+ """Return the last point of the clothoid in
+ """
+ pnt_t1 = self.p_center.project(abs(self.radio + self.local['y_o']),
+ self.azi - self.g90)
+
+ return pnt_t1.project(self.local['x_o'], self.azi + math.pi)
+
+ def _pnt_ra(self):
+ """Return the first point of the clothoid out
+ """
+ return self.p_center.project(abs(self.radio),
+ self.azi - self.g90 - self.local['tau'])
+
+ def _pnt_da(self):
+ """Return the last point of the clothoid out
+ """
+ pnt_t1 = self.p_center.project(abs(self.radio + self.local['y_o']),
+ self.azi - self.g90)
+ return pnt_t1.project(self.local['x_o'], self.azi)
+
+ def _pnt_adp(self):
+ """Return
+ """
+ if self.radio > 0:
+ xadp = self.pnt_d.x - self.other_local['x_e'] * \
+ math.sin(-self.azi) + self.local['y_e'] * math.cos(-self.azi)
+ yadp = self.pnt_d.y + self.other_local['x_e'] * \
+ math.cos(-self.azi) + self.local['y_e'] * math.sin(-self.azi)
+
+ elif self.radio < 0:
+ xadp = self.pnt_d.x + self.other_local['x_e'] * \
+ math.sin(-self.azi) - self.local['y_e'] * math.cos(-self.azi)
+ yadp = self.pnt_d.y + self.other_local['x_e'] * \
+ math.cos(-self.azi) + self.local['y_e'] * math.sin(-self.azi)
+ return Point(xadp, yadp)
+
+ def _pnt_dap(self):
+ """ Return
+ """
+ if self.radio > 0:
+ xdap = self.pnt_d.x - self.other_local['x_e'] * \
+ math.sin(-self.azi) + self.local['y_e'] * math.cos(-self.azi)
+ ydap = self.pnt_d.y - self.other_local['x_e'] * \
+ math.cos(-self.azi) - self.local['y_e'] * math.sin(-self.azi)
+
+ elif self.radio < 0:
+ xdap = self.pnt_d.x + self.other_local['x_e'] * \
+ math.sin(-self.azi) - self.local['y_e'] * math.cos(-self.azi)
+ ydap = self.pnt_d.y - self.other_local['x_e'] * \
+ math.cos(-self.azi) - self.local['y_e'] * math.sin(-self.azi)
+ return Point(xdap, ydap)
+
+ def pnt_azimuth(self, tau_clo):
+ """Return azimuth of a point of the clothoid, given the angle tau
+ """
+ if self.inout == 'in':
+ if self.radio > 0:
+ azi1 = self.azi + tau_clo
+ elif self.radio < 0:
+ azi1 = self.azi - tau_clo
+ elif self.inout == 'out':
+ if self.radio > 0:
+ azi1 = self.azi - tau_clo
+ elif self.radio < 0:
+ azi1 = self.azi + tau_clo
+ return azi1
+
+ def cloth_global(self, x_local, y_local):
+ """Return local coordinates in global coordinates
+ """
+ if self.inout == 'in':
+ if self.radio > 0:
+ x_1 = self.pnt_d.x - x_local * math.sin(-self.azi) + \
+ y_local * math.cos(-self.azi)
+ y_1 = self.pnt_d.y + x_local * math.cos(-self.azi) + \
+ y_local * math.sin(-self.azi)
+ elif self.radio < 0:
+ x_1 = self.pnt_d.x + x_local * math.sin(self.azi) - \
+ y_local * math.cos(self.azi)
+ y_1 = self.pnt_d.y + x_local * math.cos(self.azi) + \
+ y_local * math.sin(self.azi)
+ elif self.inout == 'out':
+ if self.radio > 0:
+ x_1 = self.pnt_d.x - x_local * math.sin(self.azi) + \
+ y_local * math.cos(self.azi)
+ y_1 = self.pnt_d.y - x_local * math.cos(self.azi) - \
+ y_local * math.sin(self.azi)
+ elif self.radio < 0:
+ x_1 = self.pnt_d.x + x_local * math.sin(-self.azi) - \
+ y_local * math.cos(-self.azi)
+ y_1 = self.pnt_d.y - x_local * math.cos(-self.azi) - \
+ y_local * math.sin(-self.azi)
+ return x_1, y_1
+
+ def funct(self, leng, recta2):
+ """Funtion for use with bisecc
+ """
+ rad_i = self.a_clot ** 2 / leng
+ tau_i = leng / (2 * rad_i)
+ x_o, y_o = aprox_coord(leng, tau_i)
+ x_1, y_1 = self.cloth_global(x_o, y_o)
+
+ eq1 = y_1 - (recta2.pstart.y - math.tan((recta2.azimuth())) *
+ (x_1 - recta2.pstart.x))
+ return [eq1, x_1, y_1]
+
+ def find_cutoff(self, r_pnt):
+ """Return the cutoff between this clothoid and straight, given by r_pnt
+ with its azimuth.
+ """
+ r_pnt_d = bisecc(r_pnt, self)
+ if r_pnt_d is not None:
+ if self.inout == 'out':
+ r_pnt_d.npk = self.length() - r_pnt_d.npk
+ r_pnt_d.p_type = 'Cloth_' + self.inout
+# r_pnt_d.dist_displ = r_pnt.distance(r_pnt_d)
+ return r_pnt_d
+
+if __name__ == '__main__':
+ import doctest
+ doctest.testmod()
Property changes on: grass-addons/grass7/vector/v.civil/road_base.py
___________________________________________________________________
Added: svn:mime-type
+ text/x-python
Added: svn:eol-style
+ native
Added: grass-addons/grass7/vector/v.civil/road_crosstools.py
===================================================================
--- grass-addons/grass7/vector/v.civil/road_crosstools.py (rev 0)
+++ grass-addons/grass7/vector/v.civil/road_crosstools.py 2016-07-01 22:30:22 UTC (rev 68831)
@@ -0,0 +1,589 @@
+#!/usr/bin/python
+
+"""
+Sample Python script to access vector data using GRASS Ctypes
+interface
+"""
+
+import sys
+import os
+
+import math
+import grass.script as grass
+from grass.pygrass.vector import VectorTopo
+from grass.pygrass.vector.geometry import Point
+# from grass.pygrass.vector.geometry import Line
+
+sys.path.insert(1, os.path.join(os.path.dirname(sys.path[0]), '', 'v.road'))
+import road_base as Base
+
+
+def write_objs(allrectas, radio):
+ """ Return
+ """
+ new2 = VectorTopo('bbbbb' + str(int(radio)))
+ # cols = [(u'cat', 'INTEGER PRIMARY KEY'),
+ # (u'elev', 'INTEGER')]
+
+ new2.open('w')
+ for obj in allrectas:
+ new2.write(obj)
+ # new2.table.conn.commit()
+ new2.close()
+
+
+#########################################################
+
+def generate_ptsround(radio, radio2, azimut, center):
+ """ Return
+ """
+ x_o, y_o = center.split(',')
+ radio = float(radio)
+ radio2 = float(radio2)
+ azi = float(azimut)
+
+ x_1 = float(x_o) + radio2 * math.sin(azi)
+ y_1 = float(y_o) + radio2 * math.cos(azi)
+
+ x_2 = x_1+radio*math.sin(azi + math.pi/2)
+ y_2 = y_1+radio*math.cos(azi + math.pi/2)
+
+ x_3 = x_2 + 2 * radio2 * math.sin(azi + math.pi)
+ y_3 = y_2 + 2 * radio2 * math.cos(azi + math.pi)
+
+ x_4 = x_3 + 2 * radio * math.sin(azi+3*math.pi/2)
+ y_4 = y_3 + 2 * radio * math.cos(azi+3*math.pi/2)
+
+ x_5 = x_4 + 2 * radio2 * math.sin(azi)
+ y_5 = y_4 + 2 * radio2 * math.cos(azi)
+
+ x_6 = x_5 + (radio) * math.sin(azi+math.pi/2)
+ y_6 = y_5 + (radio) * math.cos(azi+math.pi/2)
+
+ return [[x_1, y_1, 0], [x_2, y_2, 0], [x_3, y_3, 0], [x_4, y_4, 0],
+ [x_5, y_5, 0], [x_6, y_6, 0]]
+
+
+class InterAlign(object):
+ """ Return
+ """
+ def __init__(self, name_map, cat):
+ """ Return
+ """
+ self.cat = cat
+ self.name = name_map
+ self.izq = ''
+
+ topo = VectorTopo(name_map)
+ topo.open('r', layer=1)
+ line1 = topo.read(cat)
+
+ self.type = line1.attrs['type']
+ self.pk_ini = float(''.join(line1.attrs['pk'].split('+')))
+ self.pto_ini = Base.RoadPoint(line1[0])
+ self.pto_fin = line1[-1]
+ self.param = float(line1.attrs['param'].split('=')[1])
+ self.center = None
+ self.recta = None
+
+ self.out = {'pks_in': [], 'pks_out': [], 'radios': [], 'dif': []}
+
+ topo.close()
+
+ topo.open('r', layer=2)
+ self.azimut_ini = topo.read(cat).attrs['azimut']
+ topo.close()
+
+ if self.type == 'Curve':
+ self.init_curve(topo)
+
+ elif self.type == 'Straight':
+ self.init_straight()
+ else:
+ grass.message(' not yet implemented')
+
+ def init_curve(self, topo):
+ """ Return
+ """
+ topo.open('r', layer=3)
+ for center in range(1, topo.number_of("points") + 1):
+ if isinstance(topo.read(center), Point):
+ cat_curve = topo.read(center).attrs['param'][1:]
+ if self.cat == int(cat_curve):
+ self.center = Base.RoadPoint(topo.read(center))
+ self.azimut_ini = self.center.azimuth(self.pto_ini)
+
+ topo.close()
+
+ def init_straight(self):
+ """ Return
+ """
+ self.azimut_ini = self.pto_ini.azimuth(self.pto_fin)
+ self.recta = Base.Straight(self.pto_ini, None, self.azimut_ini, 10)
+
+
+class Intersections(object):
+ """ Return
+ """
+ def __init__(self, name_map1, cat1, izq1, name_map2, cat2, izq2,
+ inout=None, rounda=None):
+ """ Return
+ """
+ self.plant1 = InterAlign(name_map1, cat1)
+ self.plant2 = InterAlign(name_map2, cat2)
+
+ self.set_izq1(izq1)
+ self.set_izq2(izq2)
+
+ self.dist1 = []
+ self.dist2 = []
+ self.radios = []
+
+ self.rounda = rounda
+
+ if inout == 'In': # options 'In' or 'Out'
+ self.inout = -1
+ else:
+ self.inout = 1
+
+ def _get_dif(self, d_1, d_2, radio):
+ """ Return
+ """
+ if d_1 > d_2:
+ dtmp = d_1
+ d_1 = d_2
+ d_2 = dtmp
+ dif = round(d_2 - d_1, 6)
+ else:
+ dif = 0
+ return [round(d_1, 6), round(d_2, 6), radio, dif]
+
+ def _get_radio_leng(self, plant, radio, dist):
+ """ Return
+ """
+ if plant.param < 0:
+ if plant.izq == 'Izq':
+ r_b = abs(plant.param) - radio - dist
+ else:
+ r_b = abs(plant.param) + radio + dist
+ else:
+ if plant.izq == 'Izq':
+ r_b = abs(plant.param) + radio + dist
+ else:
+ r_b = abs(plant.param) - radio - dist
+ return r_b
+
+ def _get_azi_inout(self, plant, azi_c1c2, ang_a):
+ """ Return
+ """
+ if plant.param < 0:
+ azi = azi_c1c2 - ang_a * self.inout
+ else:
+ azi = azi_c1c2 + ang_a * self.inout
+ return azi
+
+ def _get_alpha(self, azi_1, azi_2):
+ """ Return
+ """
+ if azi_1 < 0:
+ azi_1 = self._azi_neg(abs(azi_1))
+ if azi_2 < 0:
+ azi_2 = self._azi_neg(abs(azi_2))
+ alpha = abs(azi_1 - azi_2)
+ if alpha > math.pi:
+ alpha = 2 * math.pi - alpha
+ return alpha
+
+ def _check_azimuth(self, azi):
+ """ Return
+ """
+ if azi > math.pi:
+ return azi - 2 * math.pi
+ elif azi < 0:
+ return azi + 2 * math.pi
+ return azi
+
+ def _azi_neg(self, azi):
+ """ Return
+ """
+ if azi <= math.pi:
+ return azi + math.pi
+ else:
+ return azi - math.pi
+
+ def _get_azi_inout2(self, azi):
+ """ Return
+ """
+ if self.inout == -1:
+ return self._azi_neg(azi)
+ else:
+ return azi
+
+ def set_izq1(self, izq):
+ """ Return
+ """
+ if izq == "Izq":
+ self.izq1 = -1
+ else:
+ self.izq1 = 1
+ self.plant1.izq = izq
+
+ def set_izq2(self, izq):
+ """ Return
+ """
+ if izq == "Izq":
+ self.izq2 = -1
+ else:
+ self.izq2 = 1
+ self.plant2.izq = izq
+
+ def get_intersect(self, ind):
+ """ Return
+ """
+ dist1 = [p for p in self.dist1 if p != -1]
+ dist2 = [p for p in self.dist2 if p != -1]
+ if self.plant1.type == 'Straight' and self.plant2.type == 'Curve':
+
+ grass.message('straight_curve')
+ return self.straight_curve(self.radios[ind], dist1[ind],
+ dist2[ind])
+
+ elif self.plant1.type == 'Straight' and self.plant2.type == 'Straight':
+
+ grass.message('straight_straight')
+ return self.straight_straight(self.radios[ind], dist1[ind],
+ dist2[ind])
+
+ elif self.plant1.type == 'Curve' and self.plant2.type == 'Curve':
+
+ grass.message('curve_curve')
+ return self.curve_curve(self.radios[ind], dist1[ind],
+ dist2[ind])
+
+ def straight_straight(self, radio, dist1, dist2):
+ """ Return
+ """
+ # Buscamos el centro del circulo
+ recta11 = self.plant1.recta.parallel(dist1 + radio, self.izq1)
+ recta22 = self.plant2.recta.parallel(dist2 + radio, self.izq2)
+ pto_c = recta11.cutoff(recta22)
+
+ recta_r1 = self.plant1.recta.parallel(dist1, self.izq1)
+ recta_r2 = self.plant2.recta.parallel(dist2, self.izq2)
+ pto_v = recta_r1.cutoff(recta_r2)
+
+ # Punto de corte de la recta centro-vertice con el circulo
+ pto_p = pto_c.project(radio, pto_c.azimuth(pto_v))
+
+ # Rectas perpendiculares de xc,yc y xp,yp al eje 1
+ azi_1 = recta11.azimuth() - self.izq1 * math.pi / 2
+ pto_t1 = pto_c.project(dist1 + radio, azi_1)
+ recta_p1 = Base.Straight(pto_p, None, azi_1, 10)
+ pto_p1 = self.plant1.recta.cutoff(recta_p1)
+
+ # Rectas perpendiculares de xc,yc y xp,yp al eje 2
+ azi_2 = recta22.azimuth() - self.izq2 * math.pi / 2
+ pto_t2 = pto_c.project(dist2 + radio, azi_2)
+ recta_p2 = Base.Straight(pto_p, None, azi_2, 10)
+ pto_p2 = self.plant2.recta.cutoff(recta_p2)
+
+ d_1 = self.plant1.pto_ini.distance(pto_t1) + self.plant1.pk_ini
+ d_2 = self.plant1.pto_ini.distance(pto_p1) + self.plant1.pk_ini
+ d_3 = self.plant2.pto_ini.distance(pto_t2) + self.plant2.pk_ini
+ d_4 = self.plant2.pto_ini.distance(pto_p2) + self.plant2.pk_ini
+
+ return [self._get_dif(d_1, d_2, radio), self._get_dif(d_3, d_4, radio)]
+
+ def curve_curve(self, radio, dist1, dist2):
+ """ Return
+ """
+ azi_c1c2 = self.plant1.center.azimuth(self.plant2.center)
+
+ r_b = self._get_radio_leng(self.plant1, radio, dist1)
+ r_a = self._get_radio_leng(self.plant2, radio, dist2)
+ r_c = self.plant1.center.distance(self.plant2.center)
+
+ ang_a = math.acos((r_b ** 2 + r_c ** 2 - r_a ** 2) / (2 * r_b * r_c))
+ # ang_b = math.acos((r_a ** 2 + r_c ** 2 - r_b ** 2) / (2 * r_a * r_c))
+ # ang_c = math.pi - ang_a - ang_b
+
+ azi_c1c = self._get_azi_inout(self.plant1, azi_c1c2, ang_a)
+
+ pto_c = self.plant1.center.project(r_b, azi_c1c)
+
+ alpha = self._get_alpha(azi_c1c, self.plant1.azimut_ini)
+ pk_1 = self.plant1.pk_ini + alpha * abs(self.plant1.param)
+
+ azi_c2c = self.plant2.center.azimuth(pto_c)
+ alpha = self._get_alpha(azi_c2c, self.plant2.azimut_ini)
+ pk_2 = self.plant2.pk_ini + alpha * abs(self.plant2.param)
+
+ # roundabout
+ if self.rounda:
+ pto_p = pto_c.project(radio, azi_c2c, self.izq2)
+ else:
+ if self.plant1.param * self.plant2.param > 0:
+ beta = self._get_alpha(-self.izq1 * azi_c1c,
+ -self.izq2 * azi_c2c) / 2
+ else:
+ beta = -self._get_alpha(-self.izq1 * azi_c1c,
+ self.izq2 * azi_c2c) / 2
+ if self.plant1.izq == 'Izq':
+ pto_p = pto_c.project(radio, azi_c1c -
+ self.izq2 * self.izq1 * self.inout *
+ beta)
+ else:
+ pto_p = pto_c.project(radio, self._azi_neg(azi_c1c) -
+ self.izq2 * self.izq1 * self.inout *
+ beta)
+
+ azi_c1p = self.plant1.center.azimuth(pto_p)
+ azi_c2p = self.plant2.center.azimuth(pto_p)
+
+ alpha = self._get_alpha(azi_c1p, self.plant1.azimut_ini)
+ pk_11 = self.plant1.pk_ini + alpha * abs(self.plant1.param)
+
+ alpha = self._get_alpha(azi_c2p, self.plant2.azimut_ini)
+ pk_22 = self.plant2.pk_ini + alpha * abs(self.plant2.param)
+
+ #
+ recta_c2c = Base.Straight(self.plant2.center, pto_c)
+ recta_c1c = Base.Straight(self.plant1.center, pto_c)
+
+ write_objs([pto_c, pto_p, recta_c1c.get_line(), recta_c2c.get_line()],
+ radio)
+
+ return [self._get_dif(pk_1, pk_11, radio),
+ self._get_dif(pk_2, pk_22, radio)]
+
+ def straight_curve(self, radio, dist1, dist2):
+ """ Return
+ """
+ azi_ini = self._get_azi_inout2(self.plant1.azimut_ini)
+ # Giro a la der
+ azi_1 = self._check_azimuth(self.plant1.azimut_ini + math.pi / 2)
+
+ recta1 = Base.Straight(self.plant2.center, None, azi_1, 10)
+ pto_c2 = self.plant1.recta.cutoff(recta1)
+ d_2 = self.plant2.center.distance(pto_c2)
+ azi_center = pto_c2.azimuth(self.plant2.center)
+
+ if azi_1 == azi_center:
+ l_s = abs(radio + dist1 + d_2 * self.izq1)
+ else:
+ l_s = abs(radio + dist1 - d_2 * self.izq1)
+
+ hip = self._get_radio_leng(self.plant2, radio, dist2)
+ alpha = math.asin(l_s / hip)
+
+ l_t1 = hip * math.cos(alpha)
+ pto_t1 = pto_c2.project(l_t1, azi_ini)
+
+ pto_c = self.plant2.center.project(hip, azi_ini - self.inout * alpha)
+ azi_c1c = self.plant2.center.azimuth(pto_c)
+
+ if self.rounda:
+ pto_p = pto_c.project(radio, azi_c1c, -self.izq2)
+ else:
+ if self.plant2.param < 0:
+ beta = -1 * self.izq1 * self.izq2 * \
+ self._get_alpha(azi_c1c, pto_t1.azimuth(pto_c))
+ else:
+ beta = self.izq1 * self.izq2 * \
+ self._get_alpha(azi_c1c, pto_c.azimuth(pto_t1))
+
+ pto_p = pto_c.project(radio, pto_c.azimuth(pto_t1) + beta / 2)
+
+ recta_p = Base.Straight(pto_p, None, azi_ini - self.inout *
+ self.izq1 * math.pi / 2, 10)
+ pto_t2 = self.plant1.recta.cutoff(recta_p)
+
+ d_1 = self.plant1.pto_ini.distance(pto_t1) + self.plant1.pk_ini
+ d_2 = self.plant1.pto_ini.distance(pto_t2) + self.plant1.pk_ini
+
+ azi_c1p = self.plant2.center.azimuth(pto_p)
+
+ alpha = self._get_alpha(azi_c1c, self.plant2.azimut_ini)
+ pk1 = self.plant2.pk_ini + alpha * abs(self.plant2.param)
+
+ alpha = self._get_alpha(azi_c1p, self.plant2.azimut_ini)
+ pk2 = self.plant2.pk_ini + alpha * abs(self.plant2.param)
+
+ write_objs([pto_c2, self.plant2.center, pto_c, pto_t1, pto_p, pto_t2],
+ radio)
+
+ return [self._get_dif(d_1, d_2, radio), self._get_dif(pk1, pk2, radio)]
+
+ def get_pklist(self):
+ """ Return
+ """
+ dist1 = [p for p in self.dist1 if p != -1]
+ dist2 = [p for p in self.dist2 if p != -1]
+
+ if len(dist1) <= len(dist2):
+ side = len(dist1)
+ else:
+ side = len(dist2)
+
+ pklist = [[], []]
+ pklist2 = [[], []]
+ pklist_ini = [[], []]
+ pklist_ini2 = [[], []]
+ for i in range(side):
+
+ intersec = self.get_intersect(i)
+
+ for j, inter in enumerate(intersec):
+ dista = dist1[i]
+ if j == 1:
+ dista = dist2[i]
+ if inter[0] not in pklist:
+ pklist[j].append(inter[0])
+ pklist_ini[j].append([inter[0], [inter[2]], [inter[3]],
+ [dista], i])
+ else:
+ ind = pklist[j].index(inter[0])
+ pklist_ini[j][ind][1].append(inter[2])
+ pklist_ini[j][ind][2].append(inter[3])
+ pklist_ini[j][ind][3].append(dista)
+
+ if inter[1] not in pklist2:
+ pklist2[j].append(inter[1])
+ pklist_ini2[j].append([inter[1], [dista], i])
+ else:
+ ind = pklist2[j].index(inter[1])
+ pklist_ini2[j][ind][1].append(dista)
+
+ return [pklist, pklist2, pklist_ini, pklist_ini2]
+
+ def make_intersect(self, write=False):
+ """ Return
+ """
+ pklist, pklist2, pklist_ini, pklist_ini2 = self.get_pklist()
+
+ sal1 = self.get_tablesql_in(pklist_ini[0], self.plant1, self.dist1)
+ sal2 = self.get_tablesql_out(pklist_ini2[0], self.plant1, self.dist1)
+
+ all_pklist1 = pklist[0] + pklist2[0]
+ all_sal0 = sal1 + sal2
+
+ sal0 = 'v.road add=row name=' + self.plant1.name.split('__')[0] + \
+ ' tab_type=Displ pklist="' + \
+ ','.join([str(p) for p in all_pklist1]) + '"'
+
+ grass.message(sal0)
+ grass.message(all_sal0)
+ if write:
+ os.system(sal0)
+ os.system(all_sal0)
+
+ if self.plant1.izq != self.plant2.izq:
+ sal1 = self.get_tablesql_in(pklist_ini[1], self.plant2,
+ self.dist2[::-1])
+ sal2 = self.get_tablesql_out(pklist_ini2[1], self.plant2,
+ self.dist2[::-1])
+ else:
+ sal1 = self.get_tablesql_in(pklist_ini[1], self.plant2,
+ self.dist2)
+ sal2 = self.get_tablesql_out(pklist_ini2[1], self.plant2,
+ self.dist2)
+
+ all_pklist2 = pklist[1] + pklist2[1]
+ all_sal0 = sal1 + sal2
+
+ sal0 = 'v.road add=row name=' + self.plant2.name.split('__')[0] + \
+ ' tab_type=Displ pklist="' + \
+ ','.join([str(p) for p in all_pklist2]) + '"'
+
+ grass.message(sal0)
+ grass.message(all_sal0)
+ if write:
+ os.system(sal0)
+ os.system(all_sal0)
+
+ def get_tablesql_in(self, pklist_ini, plant, distances):
+ """ Return
+ """
+ name = plant.name.split('__')[0]
+
+ sal = 'echo " \n'
+ for i, npk in enumerate([p[0] for p in pklist_ini]):
+
+ sal += 'UPDATE ' + name + '_Displ SET '
+ if plant.izq == 'Izq':
+ sal += 'sec_left=\''
+ else:
+ sal += 'sec_right=\''
+
+ for dist in distances:
+
+ for len_d in pklist_ini[i][3]:
+ if dist == len_d:
+ sal += str(len_d) + ' 0;'
+ else:
+ sal += '-1 0;'
+ sal = sal[:-1] + '\''
+
+ if plant.izq == 'Izq':
+ sal += ', type_left=\''
+ else:
+ sal += ', type_right=\''
+
+ for dist in distances:
+
+ for j, len_d in enumerate(pklist_ini[i][3]):
+ if dist == len_d:
+ sal += 'r' + str(pklist_ini[i][1][j]) + ',' + \
+ str(pklist_ini[i][2][j]) + ';'
+ else:
+ sal += 'l;'
+ sal = sal[:-1] + '\''
+
+ sal += ' WHERE pk=' + str(npk) + ';\n'
+ sal += '" | db.execute input=- \n'
+ return sal
+
+ def get_tablesql_out(self, pklist_ini2, plant, distances):
+ """ Return
+ """
+ name = plant.name.split('__')[0]
+ sal = 'echo " \n'
+ for i, npk in enumerate([p[0] for p in pklist_ini2]):
+
+ sal += 'UPDATE ' + name + '_Displ SET '
+ if plant.izq == 'Izq':
+ sal += 'sec_left=\''
+ else:
+ sal += 'sec_right=\''
+
+ for dist in distances:
+
+ for len_d in pklist_ini2[i][1]:
+ if dist == len_d:
+ sal += str(len_d) + ' 0;'
+ else:
+ sal += '-1 0;'
+ sal = sal[:-1] + '\''
+
+ if plant.izq == 'Izq':
+ sal += ', type_left=\''
+ else:
+ sal += ', type_right=\''
+
+ for dist in distances:
+ sal += 'l;'
+ sal = sal[:-1] + '\''
+
+ sal += ' WHERE pk=' + str(npk) + ';\n'
+ sal += '" | db.execute input=- \n'
+ return sal
+
+
+# =============================================
+# Main
+# =============================================
+
+if __name__ == '__main__':
+ import doctest
+ doctest.testmod()
+#
Added: grass-addons/grass7/vector/v.civil/road_displ.py
===================================================================
--- grass-addons/grass7/vector/v.civil/road_displ.py (rev 0)
+++ grass-addons/grass7/vector/v.civil/road_displ.py 2016-07-01 22:30:22 UTC (rev 68831)
@@ -0,0 +1,720 @@
+# -*- coding: utf-8 -*-
+"""
+Created on Sat Aug 2 16:52:30 2014
+
+ at author: meskal
+"""
+
+#
+# import pygrass modules
+#
+import math
+# import grass.script as grass
+import re
+from grass.pygrass.vector import VectorTopo
+import road_base as Base
+from road_plant import Aligns
+# from grass.pygrass.vector.geometry import Point
+from grass.pygrass.vector.geometry import Line
+# from grass.pygrass.vector.geometry import Boundary
+# from grass.pygrass.vector.geometry import Area
+import road_plant as Plant
+
+
+def write_objs(allrectas, radio):
+ """
+ """
+ new2 = VectorTopo('AACC__' + str(int(radio)))
+ # cols = [(u'cat', 'INTEGER PRIMARY KEY'),
+ # (u'elev', 'INTEGER')]
+
+ new2.open('w')
+ for obj in allrectas:
+ new2.write(obj)
+ # new2.table.conn.commit()
+ new2.close()
+
+
+# =============================================
+# Parallel
+# =============================================
+
+class Parallel(Base.RoadObj, object):
+ """ Return
+ """
+ def __init__(self, pk1, pk2, dist1, dist2, g90, plant=None):
+ """ Return
+ """
+ self.pk1 = pk1
+ self.dist1 = dist1
+ self.pk2 = pk2
+ self.dist2 = dist2
+ self.plant = plant
+
+ self.g90 = g90
+
+ self.line = None
+
+ super(Parallel, self).__init__(self.length())
+
+ def __str__(self):
+ return ("PARALLEL(" + str(self.pk1) + ", " + str(self.pk2) +
+ ", " + str(self.dist1) + ", " + str(self.dist2) + ", " +
+ str(self.g90) + ")")
+
+ def __repr__(self):
+
+ return ("Parallel(" + str(self.pk1) + ", " + str(self.pk2) +
+ ", " + str(self.dist1) + ", " + str(self.dist2) + ", " +
+ str(self.g90) + ")")
+
+ def length(self):
+ """ Return
+ """
+ if self.line:
+ return self.line.length()
+ else:
+ return -1
+
+ def param(self):
+ """ Return
+ """
+ return 'L=' + str(round(self.length(), 3))
+
+ def get_roadpoint(self, start, r_pnt=None):
+ """ Return
+ """
+ distx = self.dist1 + ((start - self.pk1) *
+ (self.dist2 - self.dist1)) / (self.pk2 -
+ self.pk1)
+ if not r_pnt:
+ r_pnt = self.plant.get_roadpoint(start)
+ if r_pnt.azi == 0:
+ r_pnt.azi = math.pi/2
+ r_pnt_d = r_pnt.parallel(distx, self.g90)
+
+ r_pnt_d.dist_displ = distx
+ return [r_pnt_d]
+
+ def get_roadpnts(self, start, end, interv):
+ """ Return
+ """
+ if start == 0:
+ start = int(self.pk1)
+ if end == -1:
+ end = int(self.pk2)
+ list_pts = []
+ for pki in range(start, end, interv):
+ list_pts.append(self.get_roadpoint(pki)[0])
+ self.line = Line(list_pts)
+ return list_pts
+
+ def find_cutoff(self, r_pnt):
+ """ Return
+ """
+ return self.get_roadpoint(r_pnt.npk, r_pnt)[0]
+
+
+# =============================================
+# Parallel
+# =============================================
+
+class DisplLine(Aligns, object):
+ """ Return
+ """
+ contador = 0
+ contador_left = 0
+ contador_right = 0
+
+ def __init__(self, lists, left=True, polygon=None, plant=None):
+ """ Return
+ """
+ DisplLine.contador += 1
+ if left:
+ DisplLine.contador_left += 1
+ else:
+ DisplLine.contador_right += 1
+
+ self.pks = lists[0]
+ self.dist = lists[1]
+ self.elev = lists[2]
+ self.typeline = lists[3]
+
+ self.left = left
+ self.polygon = polygon
+ self.plant = plant
+
+ self.list_lim = []
+ self.elev_lim = []
+
+ self.g90 = -math.pi / 2
+ self.num = DisplLine.contador_left
+ if not left:
+ self.g90 = math.pi / 2
+ self.num = DisplLine.contador_right
+
+ self._fix_line()
+ d_alings = self._init_aligns()
+
+ super(DisplLine, self).__init__(d_alings)
+
+ def __str__(self):
+ """ Return
+ """
+ return str(self.dist)
+
+# @staticmethod
+# def total():
+# """ Return
+# """
+# return DisplLine.contador
+
+ def _intbool(self):
+ """Return
+ """
+ if self.left is True:
+ return -1
+ else:
+ return 1
+
+ def _fix_line(self):
+ """ Return
+ """
+ dist = []
+ pks = []
+ elev = []
+ typeline = []
+ for j in range(len(self.dist)):
+ if self.dist[j] == -1:
+ continue
+ if j != len(self.dist) - 1:
+ if self.dist[j] == 0 and self.dist[j + 1] == 0:
+ continue
+ dist.append(self.dist[j])
+ pks.append(self.pks[j])
+ elev.append(self.elev[j])
+ typeline.append(self.typeline[j])
+ self.dist = dist
+ self.pks = pks
+ self.elev = elev
+ self.typeline = typeline
+
+ def _polyg_parall(self, dist):
+ """ Return
+ """
+# line = self.polygon.read(1)
+ self.polygon.open('r')
+ line = self.polygon.cat(1, 'lines', 1)[0]
+ self.polygon.close()
+
+ pnts = []
+ for i in range(len(line) - 1):
+
+ straight = Base.Straight(line[i], line[i + 1])
+ pnts.append(straight.parallel(dist, self._intbool()))
+
+ parallel = Line([pnts[0].pstart])
+ for i in range(len(pnts) - 1):
+ parallel.append(pnts[i].cutoff(pnts[i + 1]))
+ parallel.append(pnts[-1].pend)
+ return parallel
+
+ def _table_parall(self, dist):
+ """ Return
+ """
+ layer = 2
+ self.polygon.open('r')
+ tabla_plant = self.polygon.dblinks.by_layer(layer).table()
+ tabla_plant_sql = "SELECT * FROM {name};".format(name=tabla_plant.name)
+ tabla_plant_iter = tabla_plant.execute(tabla_plant_sql)
+ self.polygon.close()
+ if self.left:
+ contador = DisplLine.contador_left
+ else:
+ contador = DisplLine.contador_right
+
+ tabla = []
+ for dat in tabla_plant_iter:
+
+ cat, pk, radio, ain, aout, sobre, superelev, dc, lr = dat
+
+ if radio == 0:
+ tabla.append({'a_out': 0, 'dc_': 0, 'cat2': cat,
+ 'radio': 0, 'pk_eje': 0,
+ 'superelev': superelev, 'a_in': 0,
+ 'lr_': 0, 'widening': sobre})
+ continue
+
+ local_in = Base.cloth_local(abs(radio), ain)
+ local_out = Base.cloth_local(abs(radio), aout)
+
+ if self.left and radio < 0:
+ radio = radio + dist - (contador * sobre)
+ elif self.left and radio > 0:
+ radio = radio + dist + (contador * sobre)
+ elif not self.left and radio > 0:
+ radio = radio - dist - (contador * sobre)
+ elif not self.left and radio < 0:
+ radio = radio - dist + (contador * sobre)
+
+ if ain != 0:
+ ain = Base.clotoide_get_a(radio, local_in['y_o'],
+ contador * sobre, self.left)
+ if aout != 0:
+ aout = Base.clotoide_get_a(radio, local_out['y_o'],
+ contador * sobre, self.left)
+
+# tabla.append((0, 0, radio, ain, aout, sobre, ''))
+ tabla.append({'a_out': aout, 'dc_': 0, 'cat2': cat,
+ 'radio': radio, 'pk_eje': 0,
+ 'superelev': superelev, 'a_in': ain,
+ 'lr_': 0, 'widening': sobre})
+ return tabla
+
+ def _get_limits_plant(self, plant_d):
+ """ Return
+ """
+ list_pnts = []
+ pnts_charc = plant_d.get_charact()
+
+ for i, pnt in enumerate(pnts_charc[:-1]):
+ pnt2 = self.plant.list_aligns[i].find_cutoff(pnt)
+ if pnt2:
+ pnt2.npk += self.plant.leng_accum[i]
+
+ if not pnt2:
+ pnt2 = self.plant.list_aligns[i + 1].find_cutoff(pnt)
+ if pnt2:
+ pnt2.npk += self.plant.leng_accum[i + 1]
+
+ if not pnt2:
+ pnt2 = self.plant.list_aligns[i - 1].find_cutoff(pnt)
+ if pnt2:
+ pnt2.npk += self.plant.leng_accum[i - 1]
+ list_pnts.append(pnt2)
+ pnt2 = self.plant.list_aligns[-1].get_roadpoint(-1)[0]
+ pnt2.npk = self.plant.leng_accum[-1]
+ list_pnts.append(pnt2)
+
+ return list_pnts
+
+ def _mode_exact(self, index):
+ """ Return
+ """
+ polyg = self._polyg_parall(self.dist[index])
+ table = self._table_parall(self.dist[index])
+
+ plantalignd = Plant.Plant(polyg, table)
+ d_alings = []
+ pnts_limits = self._get_limits_plant(plantalignd)
+
+ for j, r_pnt in enumerate(pnts_limits):
+ if self.pks[index] <= r_pnt.npk <= self.pks[index + 1]:
+ self.list_lim.append(r_pnt.npk)
+ self.elev_lim.append(self.elev[index])
+ d_alings.append(plantalignd[j])
+
+ return d_alings
+
+ def _distx(self, rad, pc_d, pstart):
+ """ Return
+ """
+ recta_pnt = pstart.normal(math.pi / 2)
+ recta_c = Base.Straight(pc_d, None, pstart.azi, 10)
+ pto_corte = recta_pnt.cutoff(recta_c)
+ distxx = pc_d.distance(pto_corte)
+ seno = math.sqrt(rad ** 2 - distxx ** 2)
+ distx = pstart.distance(pto_corte) - seno
+ return distx
+
+ def _mode_curve(self, index):
+ """ Return
+ """
+ rad, center = self.typeline[index].split(",")
+
+ rad = float(rad[1:])
+ center = float(center)
+
+ pcenter = self.plant.get_roadpoint(self.pks[index] + center)
+ pc_d = pcenter.parallel(self.dist[index] + rad, self.g90)
+
+ pstart = self.plant.get_roadpoint(self.pks[index])
+ distx = self._distx(rad, pc_d, pstart)
+
+ p1_d = pstart.parallel(distx, self.g90)
+
+ pend = self.plant.get_roadpoint(self.pks[index + 1])
+
+ distx = self._distx(rad, pc_d, pend)
+ p2_d = pend.parallel(distx, self.g90)
+
+ az1 = pc_d.azimuth(p1_d)
+ az2 = pc_d.azimuth(p2_d)
+
+ alpha = abs(az2 - az1)
+ if alpha > math.pi:
+ alpha = 2 * math.pi - alpha
+
+ curve = Base.Curve(self._intbool() * rad, alpha, az1, pc_d)
+
+ return curve
+
+ def _init_aligns(self):
+ """ Return
+ """
+ d_alings = []
+ for i in range(len(self.dist) - 1):
+
+ if self.dist[i] == 0 or self.dist[i + 1] == 0:
+ self.list_lim.append(self.pks[i])
+ self.elev_lim.append(self.elev[i])
+ d_alings.append(None)
+ continue
+
+ if self.typeline[i] == 'e':
+ self.list_lim.append(self.pks[i])
+ self.elev_lim.append(self.elev[i])
+ d_alings.extend(self._mode_exact(i))
+
+ elif self.typeline[i] == 'l':
+ self.list_lim.append(self.pks[i])
+ self.elev_lim.append(self.elev[i])
+
+ paral = Parallel(self.pks[i], self.pks[i + 1], self.dist[i],
+ self.dist[i + 1], self.g90, self.plant)
+ d_alings.append(paral)
+
+ elif self.typeline[i] == 's':
+ raise ValueError('s')
+# pstart = plant.get_roadpoint(self.pks[i])
+# p1_x = pstart.x + self.dist[i]*math.sin(pstart.azi+self.g90)
+# p1_y = pstart.y + self.dist[i]*math.cos(pstart.azi+self.g90)
+#
+# pend = plant.get_roadpoint(self.pks[i+1])
+# p2_x = pend.x + self.dist[i]*math.sin(pend.azi+self.g90)
+# p2_y = pend.y + self.dist[i]*math.cos(pend.azi+self.g90)
+#
+# recta = Base.Straight(Point(p1_x, p1_y), Point(p2_x, p2_y))
+
+ elif re.search(r'^r', self.typeline[i]):
+ self.list_lim.append(self.pks[i])
+ self.elev_lim.append(self.elev[i])
+ d_alings.append(self._mode_curve(i))
+
+ else:
+ raise ValueError('Type not suported:' + self.typeline[i])
+
+ if self.pks[-1] not in self.list_lim:
+ self.list_lim.append(self.pks[-1])
+ self.elev_lim.append(self.elev[-1])
+
+ return d_alings
+
+ def get_left(self):
+ """ Return
+ """
+ if self.left:
+ return 'left'
+ else:
+ return 'right'
+
+ def _find_superelev(self, index, r_pnt, elev, dist_displ):
+ """Return
+ """
+ for line in self.plant.superelev_lim:
+
+ if line == []:
+ continue
+
+ dist1, dist2, bom1, peralte, bom2, radio = line
+ pks_1 = dist1 + dist2
+
+ if (pks_1[0] < r_pnt.npk < pks_1[-1]):
+ break
+
+# pend_1 = [-bom1, 0, bom1, peralte, peralte, bom2, 0, -bom2]
+# pend_2 = [-bom1, -bom1, -bom1, -peralte, -peralte, -bom2, -bom2, -bom2]
+
+# elev2 = elev / dist_displ
+ bom1 = bom1 * dist_displ * 0.01
+ bom2 = bom2 * dist_displ * 0.01
+ peralte = peralte * dist_displ * 0.01
+ pend_11 = [elev, elev + bom1, elev + bom1 + bom1,
+ elev + bom1 + peralte, elev + bom1 + peralte,
+ elev + bom2 + bom2, elev + bom2, elev]
+ pend_22 = [elev, elev, elev, elev - peralte, elev - peralte,
+ elev, elev, elev]
+
+ pkini, pkfin = 0, 1
+# z_1 = - bombeo * dist_displ * 0.01
+# z_2 = - bombeo * dist_displ * 0.01
+ z_1 = elev
+ z_2 = elev
+
+ if (self.left and radio > 0) or (not self.left and radio < 0):
+
+ for i in range(len(pks_1) - 1):
+
+ if pks_1[i] < r_pnt.npk < pks_1[i + 1]:
+ pkini, pkfin = pks_1[i], pks_1[i + 1]
+ z_1 = pend_11[i]
+ z_2 = pend_11[i + 1]
+ break
+
+ elif (not self.left and radio > 0) or (self.left and radio < 0):
+
+ for i in range(0, len(pks_1) - 1, 1):
+
+ if pks_1[i] < r_pnt.npk < pks_1[i + 1]:
+ pkini, pkfin = pks_1[i], pks_1[i + 1]
+ z_1 = pend_22[i]
+ z_2 = pend_22[i + 1]
+ break
+
+ z_x = z_1 + ((r_pnt.npk - pkini) * ((z_2 - z_1) / (pkfin - pkini)))
+
+ return z_x
+
+ def get_elev(self, index, r_pnt, dist_displ):
+ """ Return
+ """
+# calzadas = 1
+# if self.plant.bombeo:
+# elev = self._find_superelev(index, r_pnt, self.plant.bombeo,
+# dist_displ)
+#
+# else:
+ elev = self.elev_lim[index] + ((r_pnt.npk - self.list_lim[index]) *
+ (self.elev_lim[index + 1] -
+ self.elev_lim[index])) / \
+ (self.list_lim[index + 1] -
+ self.list_lim[index])
+ if self.plant.bombeo:
+ elev = self._find_superelev(index, r_pnt, elev, dist_displ)
+
+ return elev
+
+ def find_cutoff(self, r_pnt):
+ """ Return
+ """
+
+ for i in range(len(self.list_lim) - 1):
+ if isinstance(self.list_aligns[i], Base.Curve):
+ cuv_lim = r_pnt.npk <= self.list_lim[i + 1]
+ else:
+ cuv_lim = r_pnt.npk < self.list_lim[i + 1]
+
+ if self.list_lim[i] <= r_pnt.npk and cuv_lim:
+
+ if self.list_aligns[i] is not None:
+ r_pnt_d = self.list_aligns[i].find_cutoff(r_pnt)
+
+ if r_pnt_d is not None:
+ r_pnt_d.dist_displ = \
+ round(r_pnt_d.distance2(r_pnt.point2d), 4)
+ elev = self.get_elev(i, r_pnt, r_pnt_d.dist_displ)
+ r_pnt_d.z = elev + r_pnt.z
+ if r_pnt_d.dist_displ == 0:
+ r_pnt_d.incli = 0
+ else:
+ r_pnt_d.incli = math.atan(elev/r_pnt_d.dist_displ)
+
+ r_pnt_d.acum_pk = self.list_lim[i] + r_pnt_d.npk
+
+ return r_pnt_d
+
+ def get_pnts_displ(self, list_r_pnts, line=False):
+ """ Return a displaced line of a given axis
+ """
+ list_pnts_d = []
+
+ for r_pnt in list_r_pnts:
+ list_pnts_d.append(self.find_cutoff(r_pnt))
+
+ if line:
+ return Line(list_pnts_d)
+ else:
+ return list_pnts_d
+
+ def set_roadline(self, roadline):
+ """ Return
+ """
+ puntos = self.get_pnts_displ(roadline, line=False)
+
+ # Name lenght type param rgb
+ attrs = ['Displ_' + str(self.num), self.length(), self.get_left(),
+ self.num, '0:128:128']
+ self.roadline = Base.RoadLine(puntos, attrs, 'Displ_' + str(self.num))
+
+
+# =============================================
+# Parallel
+# =============================================
+
+class Displaced(object):
+ """ Return
+ """
+ def __init__(self, polygon, tabla_iter, plant):
+ """ Return
+ """
+ self.polygon = polygon
+ self.tabla_iter = tabla_iter
+ self.plant = plant
+
+ self.displines = []
+ self.displines_left = []
+ self.displines_right = []
+ self.pks = []
+
+ self._init_displ()
+
+ def __getitem__(self, index):
+ return self.displines[index]
+
+ def __setitem__(self, index, value):
+ self.displines[index] = value
+
+ def __delitem__(self, index):
+ del self.displines[index]
+
+ def __len__(self):
+ return len(self.displines)
+
+ def __str__(self):
+ """ Return
+ """
+ return "LINESTRING(%s)"
+
+ def _init_displ(self):
+ """ Return
+ """
+ d_left = []
+ type_left = []
+ d_right = []
+ type_right = []
+
+ for i, dat in enumerate(self.tabla_iter):
+
+ self.pks.append(dat['pk'])
+ if ';' in dat['sec_left']:
+ d_left.append(dat['sec_left'].split(';'))
+ else:
+ d_left.append(dat['sec_left'])
+
+ if ';' in dat['sec_right']:
+ d_right.append(dat['sec_right'].split(';'))
+ else:
+ d_right.append(dat['sec_right'])
+
+ if dat['type_left'] != '':
+ type_left.append(dat['type_left'].split(';'))
+ else:
+ type_left.append(['l'] * len(d_left[i]))
+
+ if dat['type_right'] != '':
+ type_right.append(dat['type_right'].split(';'))
+ else:
+ type_right.append(['l'] * len(d_right[i]))
+
+ self._generate(d_left, type_left, left=True)
+ self._generate(d_right, type_right, left=False)
+
+ def _generate(self, disp, types, left):
+ """ Return
+ """
+ rango1 = range(len(types[0]))
+
+ disp = [[[float(p) for p in row[i].split()] for row in disp]
+ for i in range(len(disp[0]))]
+ types = [[row[i] for row in types] for i in rango1]
+
+ if left:
+ disp = disp[::-1]
+ types = types[::-1]
+
+ for i, lin in enumerate(disp):
+ types2 = types[:]
+ lin2 = [[row[j] for row in lin] for j in range(len(lin[0]))]
+
+ displine = DisplLine([self.pks[:], lin2[0], lin2[1], types2[i][:]],
+ left, self.polygon, self.plant)
+
+ self.displines.append(displine)
+ if left:
+ self.displines_left.append(displine)
+ else:
+ self.displines_right.append(displine)
+
+ def find_cutoff(self, r_pnt):
+ """ Return all displaced points of a given axis point
+ """
+ list_pnts_d_left = []
+ list_pnts_d_right = []
+ for d_line in self.displines:
+ pnt = d_line.find_cutoff(r_pnt)
+ if d_line.left:
+# if pnt is not None:
+ list_pnts_d_left.append(pnt)
+ else:
+# if pnt is not None:
+ list_pnts_d_right.append(pnt)
+ return [list_pnts_d_left, list_pnts_d_right]
+
+ def get_pnts_trans(self, list_r_pnts):
+ """ Return
+ """
+ list_pnts_d = []
+ for r_pnt in list_r_pnts:
+ list_pnts_d.append(self.find_cutoff(r_pnt))
+ return list_pnts_d
+
+ def get_lines(self):
+ """ Return
+ """
+ list_attrs = []
+ list_lines = []
+ for i, displ in enumerate(self.displines):
+
+ objs, values = displ.roadline.get_line_attrs(1)
+ list_lines.extend(objs)
+ list_attrs.extend(values)
+ return list_lines, list_attrs
+
+ def get_charact(self):
+ """ Return
+ """
+ list_lines = []
+ list_attrs = []
+ for i, displ in enumerate(self.displines):
+ obj, attr = displ.get_charact_pnts()
+ list_lines.extend(obj)
+ for att in attr:
+ att.append('Displ=' + str(i + 1))
+ list_attrs.extend(attr)
+ return list_lines, list_attrs
+
+ def set_roadlines(self, roadline):
+ """ Return
+ """
+ for displ in self.displines:
+ displ.set_roadline(roadline)
+
+ def get_areas(self, opts):
+ """ Return
+ """
+ opts = [opt.split('-') for opt in opts.split(',') if ',' in opts]
+
+ list_lines = []
+ list_attrs = []
+ for j, opt in enumerate(opts):
+
+ lines = self[int(opt[0]) - 1].roadline.get_area(
+ self[int(opt[1]) - 1].roadline)
+ list_attrs.extend([str(j + 1) for _ in range(len(lines))])
+ list_lines.extend(lines)
+
+ return list_lines, list_attrs
+
+if __name__ == '__main__':
+ import doctest
+ doctest.testmod()
Property changes on: grass-addons/grass7/vector/v.civil/road_displ.py
___________________________________________________________________
Added: svn:mime-type
+ text/x-python
Added: svn:eol-style
+ native
Added: grass-addons/grass7/vector/v.civil/road_marks.py
===================================================================
--- grass-addons/grass7/vector/v.civil/road_marks.py (rev 0)
+++ grass-addons/grass7/vector/v.civil/road_marks.py 2016-07-01 22:30:22 UTC (rev 68831)
@@ -0,0 +1,85 @@
+# -*- coding: utf-8 -*-
+"""
+Created on Thu Oct 23 01:06:18 2014
+
+ at author: meskal
+"""
+
+#
+# import pygrass modules
+#
+import math
+
+# from grass.pygrass.vector import VectorTopo
+# import road_base as Base
+
+# from grass.pygrass.vector.geometry import Point
+# from grass.pygrass.vector.geometry import Line
+
+
+class Marks(object):
+ """ Return
+ """
+ def __init__(self, polygon, tabla, plant, vert):
+ """ Return
+ """
+ self.polygon = polygon
+# self.tabla_iter = tabla_iter
+ self.plant = plant
+ self.vert = vert
+
+ self.tabla = tabla
+# self.init_marks()
+
+ def __str__(self):
+ """ Return
+ """
+ return "TransLine(" + str(self.tabla) + ")"
+
+# def init_marks(self):
+# """ Return
+# """
+# for dats in self.tabla_iter:
+#
+# if dats[5] is not None:
+# self.list_dats.append(dict(zip(['pk', 'dist', 'elev', 'azi',
+# 'name', 'cod'], dats[1:7])))
+
+ def num_marks(self):
+ """ Return
+ """
+
+ def get_pnts(self):
+ """ Return
+ """
+ list_pnts = []
+ list_attrs = []
+ for i, dats in enumerate(self.tabla):
+
+ r_pnt = self.plant.get_roadpoint(dats['pk'])
+
+ self.vert.set_elev(r_pnt)
+
+ if ',' in dats['dist']:
+ distances = dats['dist'].split(',')
+ elevations = dats['elev'].split(',')
+ else:
+ distances = dats['dist']
+ elevations = dats['elev']
+
+ if dats['azi'] != '':
+ azi = dats['azi'].split(',')
+ else:
+ azi = ['1'] * len(distances)
+
+ for i, dist in enumerate(distances):
+ m_pnt = r_pnt.parallel(float(dist), math.pi / 2)
+ m_pnt.z = r_pnt.z + float(elevations[i])
+ m_pnt.dist_displ = dist
+ if azi[i] == '-1':
+ m_pnt.azi = m_pnt.azi + math.pi
+ list_pnts.append(m_pnt)
+ list_attrs.append([m_pnt.npk, round(90-m_pnt.azi * 180 / math.pi+360+90,
+ 4), dats['name'],
+ dats['cod'], m_pnt.dist_displ, m_pnt.z])
+ return list_pnts, list_attrs
Property changes on: grass-addons/grass7/vector/v.civil/road_marks.py
___________________________________________________________________
Added: svn:mime-type
+ text/x-python
Added: svn:eol-style
+ native
Added: grass-addons/grass7/vector/v.civil/road_plant.py
===================================================================
--- grass-addons/grass7/vector/v.civil/road_plant.py (rev 0)
+++ grass-addons/grass7/vector/v.civil/road_plant.py 2016-07-01 22:30:22 UTC (rev 68831)
@@ -0,0 +1,800 @@
+# -*- coding: utf-8 -*-
+"""
+Created on Wed Jul 23 18:37:36 2014
+
+ at author: meskal
+"""
+
+import math
+import time
+import road_base as Base
+
+# import grass.script as grass
+# from grass.pygrass.vector.geometry import Point
+from grass.pygrass.vector.geometry import Line
+# from grass.pygrass.vector.geometry import Attrs
+
+
+def time_func(funcion_f):
+ """Return
+ """
+ def funcion_r(*arg):
+ """Return
+ """
+ t_1 = time.clock()
+ res = funcion_f(*arg)
+ t_2 = time.clock()
+ print('%s tarda %0.5f ms' % (funcion_f.__name__, (t_2 - t_1) * 1000.0))
+ return res
+ return funcion_r
+
+
+# =============================================
+# ALIGNS
+# =============================================
+
+class Aligns(object):
+ """ Return
+ """
+ def __init__(self, list_aligns=None):
+ """ Return
+ """
+ self.list_aligns = list_aligns
+
+ self.leng_accum = [0]
+
+ self.length_accums()
+
+ self.roadline = None
+
+ def __getitem__(self, index):
+ return self.list_aligns[index]
+
+ def __setitem__(self, index, value):
+ self.list_aligns[index] = value
+
+ def __delitem__(self, index):
+ del self.list_aligns[index]
+
+ def __len__(self):
+ return len(self.list_aligns)
+
+ def __str__(self):
+ return self.__repr__()
+
+ def __repr__(self):
+ string = "["
+
+ for i in self.list_aligns:
+ string += str(i) + '\n'
+
+ string += "]"
+ return string
+
+ def length_accums(self):
+ """ Return
+ """
+ lon = 0
+ for ali in self.list_aligns:
+ if ali is not None:
+ ali.leng_accum = lon
+ lon += ali.length()
+ self.leng_accum.append(lon)
+
+ def length(self):
+ """ Return
+ """
+ return self.leng_accum[-1]
+
+ def get_roadpoint(self, npk):
+ """ Return
+ """
+ if npk == -1:
+ npk = self.length()
+ for i in range(len(self.leng_accum) - 1):
+
+ if self.leng_accum[i] <= npk <= self.leng_accum[i + 1]:
+
+ pnt = self.list_aligns[i].get_roadpoint(npk -
+ self.leng_accum[i])[0]
+ pnt.npk = npk
+
+ pnt.align = self.list_aligns[i].__class__.__name__ + '_' + \
+ str(i + 1)
+ return pnt
+
+# def get_line(self, list_r_pnts):
+# """ Return
+# """
+# return Line([r_pnt for r_pnt in list_r_pnts
+# if r_pnt is not None])
+
+ def get_roadpnts(self, start, end, interv, interv_c=None):
+ """ Return
+ """
+ if not interv_c:
+ interv_c = interv
+
+ if end == -1:
+ end = self.length()
+ resto = interv
+ accum = start
+ list_pts = []
+ ini = 0
+ fin = len(self.leng_accum)
+ for i in range(len(self.leng_accum) - 1):
+ if self.leng_accum[i] <= start <= self.leng_accum[i + 1]:
+ ini = i
+ if self.leng_accum[i] <= end <= self.leng_accum[i + 1]:
+ fin = i + 1
+
+ rang_int = range(0, int(self.leng_accum[-1]), int(interv))
+ rang_int_c = range(0, int(self.leng_accum[-1]), int(interv_c))
+
+ # int_ant = interv
+ rango_ant = []
+ for i in range(ini, fin):
+
+ rango = []
+ if isinstance(self.list_aligns[i], Base.Straight):
+ inter = interv
+ for j in range(len(rang_int) - 1):
+ if self.leng_accum[i] <= rang_int[j] <= self.leng_accum[i + 1]:
+ rango.append(rang_int[j])
+ else:
+ inter = interv_c
+ for j in range(len(rang_int_c) - 1):
+ if self.leng_accum[i] <= rang_int_c[j] <= self.leng_accum[i + 1]:
+ rango.append(rang_int_c[j])
+
+ if inter > self.list_aligns[i].length() + resto:
+ resto = resto + self.list_aligns[i].length()
+ continue
+
+ if rango == []:
+ rango = [rango_ant[-1] + inter]
+ accum = rango[0]
+ start2 = rango[0] - self.leng_accum[i]
+
+ if i == ini:
+ start2 = start - self.leng_accum[i]
+
+ end2 = -1
+ if i == fin:
+ end2 = end - self.leng_accum[i]
+
+ self.list_aligns[i].pts_accum = accum
+
+ pnts = self.list_aligns[i].get_roadpnts(start2, end2, inter)
+ for pnt in pnts:
+ pnt.align = self.list_aligns[i].__class__.__name__ + '_' + \
+ str(i + 1)
+ list_pts.extend(pnts)
+
+ resto = self.list_aligns[i].pts_rest
+ accum = self.list_aligns[i].pts_accum
+ # int_ant = inter
+ rango_ant = rango
+
+ r_pnt = self.list_aligns[-1].get_roadpoint(-1)[0]
+ r_pnt.align = self.list_aligns[-1].__class__.__name__ + '_' + \
+ str(len(self.list_aligns))
+ if list_pts[-1].npk != r_pnt.npk:
+ r_pnt.npk = round(r_pnt.npk, 6)
+ list_pts.append(r_pnt)
+
+ return list_pts
+
+ def get_segments_pnts(self, puntos, vert=None, line=False):
+ """ Return
+ """
+ list_lines = []
+ list_attrs = []
+ for i, ali in enumerate(self.list_aligns):
+ pnt_ini = ali.get_roadpoint(0)[0]
+ pnt_ini.align = i + 1
+ pnts_align = [pnt_ini]
+ pnts_align.extend([r_pnt for r_pnt in puntos if ali.is_in(r_pnt)])
+ pnt_end = ali.get_roadpoint(-1)[0]
+ pnt_end.align = i + 1
+ pnts_align.append(pnt_end)
+
+ if vert is not None:
+ vert.set_pnts_elev(pnts_align)
+ if line:
+ list_lines.append(Line(pnts_align))
+ else:
+ list_lines.append(pnts_align)
+ list_attrs.append([ali.get_leng_accum(), ali.__class__.__name__,
+ round(ali.length(), 3), ali.param(),
+ ali.grassrgb()])
+ return list_lines, list_attrs
+
+ def get_charact_pnts(self, lines=False):
+ """ Return
+ """
+ list_attrs = []
+ list_obj = []
+
+ for i, ali in enumerate(self.list_aligns):
+ if ali is not None:
+ r_pnt = ali.get_roadpoint(0)[0]
+ if lines:
+ pnt2 = r_pnt.project(10, r_pnt.azi - math.pi / 2)
+ list_obj.append(Line([r_pnt, pnt2]))
+ else:
+ r_pnt.align = ali.__class__.__name__ + '_' + str(i + 1)
+ list_obj.append(r_pnt)
+ list_attrs.append([r_pnt.get_pk(), r_pnt.get_azi(),
+ r_pnt.p_type, ali.param()])
+ for i, ali in enumerate(self.list_aligns[::-1]):
+ if ali is not None:
+ r_pnt = ali.get_roadpoint(-1)[0]
+ break
+ if lines:
+ pnt2 = r_pnt.project(10, r_pnt.azi - math.pi / 2)
+ list_obj.append(Line([r_pnt, pnt2]))
+ else:
+ r_pnt.align = self.list_aligns[-1].__class__.__name__ + '_' + \
+ str(len(self.list_aligns) + 1)
+ list_obj.append(r_pnt)
+ for i, ali in enumerate(self.list_aligns[::-1]):
+ if ali is not None:
+
+ list_attrs.append([ali.get_leng_accum2(),
+ r_pnt.get_azi(), r_pnt.p_type, 'L=0'])
+ break
+ return list_obj, list_attrs
+
+# def get_charact_pnts2(self):
+# """ Return
+# """
+# list_obj = []
+# r_pnt = self.list_aligns[0].get_roadpoint(0)[0]
+# r_pnt.align = self.list_aligns[0].__class__.__name__ + '_' + str(1)
+# list_obj.append(r_pnt)
+# for i, ali in enumerate(self.list_aligns):
+# if ali is not None:
+# r_pnt = ali.get_roadpoint(-1)[0]
+# r_pnt.align = ali.__class__.__name__ + '_' + str(i + 1)
+# list_obj.append(r_pnt)
+#
+# return list_obj
+
+ def get_curves_centers(self):
+ """ Return
+ """
+ list_centers = []
+ list_attrs = []
+ for i, ali in enumerate(self.list_aligns):
+ if isinstance(ali, Base.Curve):
+ list_centers.append(ali.p_center)
+ list_attrs.append(['C' + str(i + 1)])
+ return list_centers, list_attrs
+
+
+# =============================================
+# PLANT ALIGN
+# =============================================
+
+class PlantAlign(object):
+ """ Return
+ """
+ def __init__(self, dat, dat1=None, dat2=None, recta1=None, recta2=None):
+ """ Return
+ """
+ self.radio = dat['radio']
+ self.a_in = dat['a_in']
+ self.a_out = dat['a_out']
+ self.dat = dat
+ self.recta1 = recta1
+ self.recta2 = recta2
+ self.dat1 = dat1
+ self.dat2 = dat2
+
+ self.straight = None
+ self.cloth_in = None
+ self.curve = None
+ self.cloth_out = None
+
+ self.in_local = None
+ self.out_local = None
+
+ self._init_align()
+
+ def __str__(self):
+ return self.get_wkt()
+
+ def __repr__(self):
+ return ("PlantAlign( \n" + str(self.straight) + ", \n" +
+ str(self.cloth_in) + ", \n" + str(self.curve) + ", \n" +
+ str(self.cloth_out) + ")\n")
+
+ def _alpha(self):
+ """ Return
+ """
+ a_w = self.recta1.angle(self.recta2)
+ if self.radio > 0:
+ return abs(a_w - self.in_local['tau'] - self.out_local['tau'])
+ else:
+ return abs(a_w + self.in_local['tau'] + self.out_local['tau'])
+
+ def _center(self):
+ """ Return the cutoff point between this straight an a given one.
+ """
+ if self.radio == 0:
+ return Base.RoadPoint(self.recta1.pend, 0, 0)
+ else:
+ recta11 = self.recta1.parallel(abs(self.radio +
+ self.in_local['y_o']),
+ self.radio)
+ recta22 = self.recta2.parallel(abs(self.radio +
+ self.out_local['y_o']),
+ self.radio)
+ return recta11.cutoff(recta22)
+
+ def _init_align(self):
+ """ Return
+ """
+ local2_in = False
+ local2_out = False
+
+ if self.radio != 0:
+ self.in_local = Base.cloth_local(self.radio, self.a_in)
+ self.out_local = Base.cloth_local(self.radio, self.a_out)
+
+ alpha = self._alpha()
+ else:
+ alpha = 0
+
+ p_center = self._center()
+
+ if self.dat1['a_out'] < 0 and self.radio != 0:
+ local2_out = Base.cloth_local(self.dat1['radio'],
+ self.dat1['a_out'])
+ self.cloth_in = Base.Clothoid(self.a_in, self.radio,
+ self.recta1.azimuth(), 'in', local2_out,
+ p_center)
+
+ self.recta1.pend = self.cloth_in.pnt_d
+
+ if self.dat1['a_out'] < 0 and self.radio != 0:
+ self.recta1.pstart = self.cloth_in.pnt_p
+
+ if self.radio == 0:
+ az_ini = self.recta1.azimuth()
+ else:
+ az_ini = Base.azimut(p_center, self.cloth_in.pnt_r)
+ self.curve = Base.Curve(self.radio, alpha, az_ini, p_center)
+
+ if self.dat2['a_in'] < 0:
+ local2_in = Base.cloth_local(self.dat2['radio'], self.dat2['a_in'])
+ self.cloth_out = Base.Clothoid(self.a_out, self.radio,
+ self.recta2.azimuth(), 'out', local2_in,
+ p_center)
+
+ self.straight = Base.Straight(self.recta1.pstart, self.recta1.pend,
+ None, None)
+
+ def set_lengs_accum(self, leng_accum):
+ """Return the lenght accum of the aling and set the superelev limits
+ """
+
+ self.straight.leng_accum = leng_accum
+ self.cloth_in.leng_accum = self.straight.leng_accum + \
+ self.straight.length()
+ self.curve.leng_accum = self.cloth_in.leng_accum + \
+ self.cloth_in.length()
+ self.cloth_out.leng_accum = self.curve.leng_accum + self.curve.length()
+
+ return self.cloth_out.leng_accum + self.cloth_out.length()
+
+ def get_aligns(self):
+ """Return
+ """
+ list_aligns = []
+ if self.straight.length() != 0:
+ list_aligns.append(self.straight)
+ if self.cloth_in.a_clot != 0:
+ list_aligns.append(self.cloth_in)
+ if self.curve.radio != 0:
+ list_aligns.append(self.curve)
+ if self.cloth_out.a_clot != 0:
+ list_aligns.append(self.cloth_out)
+
+ return list_aligns
+
+ def get_super_lim(self, bombeo):
+ """Return
+ """
+ super_lim = []
+ tot_accum = self.cloth_out.leng_accum + self.cloth_out.length()
+
+ if (self.dat['superelev'] != '' and self.dat['superelev'] != None and
+ self.dat['superelev'] != 'None'):
+
+ dist1, dist2, bom1, peral, bom2, dist3, dist4 = \
+ [float(p) for p in self.dat['superelev'].split(',')]
+ # d1, d2, b, p, b, d2, d1
+ super_lim = [[self.cloth_in.leng_accum - dist1,
+ self.cloth_in.leng_accum,
+ self.cloth_in.leng_accum + dist2,
+ self.curve.leng_accum],
+ [self.cloth_out.leng_accum,
+ tot_accum - dist3,
+ tot_accum,
+ tot_accum + dist4], bom1, peral, bom2, self.radio]
+ elif bombeo != 0 and self.cloth_in.length() != 0 and \
+ self.cloth_out.length() != 0:
+
+ super_lim = [
+ [self.cloth_in.leng_accum - self.cloth_in.length() / 2,
+ self.cloth_in.leng_accum,
+ self.cloth_in.leng_accum + self.cloth_in.length() / 2,
+ self.curve.leng_accum],
+ [self.cloth_out.leng_accum,
+ tot_accum - self.cloth_out.length() / 2,
+ tot_accum,
+ tot_accum + self.cloth_out.length() / 2],
+ bombeo, bombeo, bombeo,
+ self.radio]
+
+ return super_lim
+
+ def get_endpnt(self):
+ """ Return
+ """
+ return self.cloth_out.pnt_d
+
+ def length(self):
+ """ Return
+ """
+ return self.straight.length() + self.cloth_in.length() + \
+ self.curve.length() + self.cloth_out.length()
+
+
+# =============================================
+# PLANT
+# =============================================
+
+class Plant(Aligns, object):
+ """ Return
+ """
+ def __init__(self, polygon=None, road_table=None,
+ table_to_plan=False, bombeo=0):
+ """ Return
+ """
+ self.bombeo = bombeo
+ self.polygon = polygon
+ self.road_table = road_table
+
+ self.straight_curve_lengs = [0]
+ self.list_aligns = []
+ self.superelev_lim = []
+
+ if table_to_plan is False:
+ self._init_poly_to_plant()
+ else:
+ self._init_table_to_plant()
+
+ super(Plant, self).__init__(self.list_aligns)
+
+ def __str__(self):
+ return self.get_wkt()
+
+# def __repr__(self):
+# return "[" + self.align + "]"
+
+# def get_wkt(self):
+# """Return a "well know text" (WKT) geometry string. ::
+# """
+# return "[" + str(self.align) + "]"
+
+ def _init_poly_to_plant(self):
+ """ Return
+ """
+ dat1 = []
+ dat2 = []
+
+ line = self.polygon
+ leng_accum = 0
+
+ for i, dat3 in enumerate(self.road_table):
+
+ if i >= 2:
+ if i == 2:
+ end_pnt = line[0]
+
+ recta1 = Base.Straight(end_pnt, line[i - 1])
+ recta2 = Base.Straight(line[i - 1], line[i])
+
+ alig = PlantAlign(dat2, dat1, dat3, recta1, recta2)
+
+ leng_accum = alig.set_lengs_accum(leng_accum)
+ self.list_aligns.extend(alig.get_aligns())
+ end_pnt = alig.get_endpnt()
+
+ self.straight_curve_lengs.append(alig.straight.length())
+ self.straight_curve_lengs.append(alig.curve.length())
+
+ self.superelev_lim.append(alig.get_super_lim(self.bombeo))
+
+ dat1 = dat2
+ dat2 = dat3
+
+ if i == len(self.road_table) - 1:
+ if len(self.road_table) == 2:
+ end_pnt = line[i - 1]
+
+ recta1 = Base.Straight(end_pnt, line[-1])
+ recta1.leng_accum = leng_accum
+ self.list_aligns.append(recta1)
+ self.straight_curve_lengs.append(recta1.length())
+
+ def _init_table_to_plant(self):
+ """ Return
+ """
+ pnt_center = Base.RoadPoint(self.polygon[0])
+ pnt_1 = Base.RoadPoint(self.polygon[1])
+ recta_1 = Base.Straight(pnt_center, pnt_1)
+
+ rectas = []
+ new_rows = []
+
+ for i, dat in enumerate(self.road_table):
+
+ new_rows.append(dat)
+
+ if dat['lr_'] != 0:
+ new_rows.append({'radio': 0.0, 'a_in': 0.0, 'a_out': 0.0,
+ 'dc_': dat['dc_'], 'lr_': dat['lr_']})
+
+ for i, dat in enumerate(new_rows[:-1]):
+
+ dat1 = new_rows[i]
+ dat2 = new_rows[i + 1]
+
+ if dat1['radio'] == 0 and dat2['radio'] == 0:
+ continue
+ elif dat1['radio'] == 0:
+ pnt_center, pnt_1, recta_1 = \
+ self._staight_curve(pnt_center, pnt_1, dat1, dat2)
+ if i == 1:
+ self.list_aligns.insert(0, recta_1)
+ self.straight_curve_lengs.insert(1, recta_1.length())
+ elif dat2['radio'] == 0:
+ pnt_center, pnt_1, recta_1 = \
+ self._curve_straight(pnt_center, pnt_1, dat1, dat2)
+
+ elif abs(dat1['radio']) > abs(dat2['radio']) and dat1['a_out'] < 0:
+ pnt_center, pnt_1, recta_1 = \
+ self._curve_high_low(pnt_center, pnt_1, dat1, dat2)
+
+ elif abs(dat1['radio']) > abs(dat2['radio']) and dat2['a_in'] < 0:
+ pnt_center, pnt_1, recta_1 = \
+ self._curve_low_high(pnt_center, pnt_1, dat1, dat2)
+ else:
+ raise ValueError('Error')
+
+ rectas.append(recta_1)
+
+ new_polygon = [rectas[0].pstart]
+ for i, recta in enumerate(rectas[:-1]):
+ if round(recta.azimuth(), 8) == round(rectas[i + 1].azimuth(), 8):
+ continue
+ new_polygon.append(recta.cutoff(rectas[i + 1]))
+ new_polygon.append(rectas[-1].pend)
+ self.polygon = Line(new_polygon)
+ self.road_table.polyline = new_polygon
+
+ def _curve_high_low(self, pnt_center, pnt_1, dat1, dat2):
+ """ Return
+ """
+ # R1>R2
+ # Calculamos los puntos de tangencia de la clotoide con los dos circulo
+ out_local = Base.cloth_local(dat1['radio'], dat1['a_out'])
+ in_local = Base.cloth_local(dat2['radio'], dat2['a_in'])
+
+ azi_in = pnt_center.azimuth(pnt_1)
+ alpha = dat2['dc_'] / dat2['radio']
+
+ if dat1['radio'] > 0 and dat2['radio'] > 0:
+ g90 = math.pi / 2
+ elif dat1['radio'] < 0 and dat2['radio'] < 0:
+ g90 = -math.pi / 2
+ else:
+ raise ValueError("Error: For change the radio sing a straight must be \
+ between the radios")
+ return None, None, None
+
+ pnt_t1 = pnt_center.project(abs(dat1['radio'] + out_local['y_o']),
+ azi_in - out_local['tau'])
+
+ pnt_t2 = pnt_t1.project(in_local['x_o'] - out_local['x_o'],
+ azi_in - out_local['tau'] + g90)
+
+ pnt_ad2 = pnt_t1.project(out_local['x_o'], azi_in - out_local['tau'] +
+ g90)
+
+ pnt_c2 = pnt_t2.project(abs(dat2['radio'] + in_local['y_o']),
+ azi_in - out_local['tau'] + 2 * g90)
+
+ pnt_ar2 = pnt_c2.project(abs(dat2['radio'], azi_in - out_local['tau'] +
+ in_local['tau']))
+
+ pnt_ra2 = pnt_c2.project(abs(dat2['radio']), azi_in -
+ out_local['tau'] + in_local['tau'] + alpha)
+
+ if dat2['a_in'] != 0:
+ cloth = Base.Clothoid(dat2['a_in'], dat2['radio'],
+ pnt_ad2.azimuth(pnt_t2), 'in', None, pnt_c2)
+ self.list_aligns.append()
+ self.straight_curve_lengs.append(cloth.length())
+
+ curve = Base.Curve(dat2['radio'], alpha, pnt_c2.azimuth(pnt_ar2),
+ pnt_c2)
+ self.list_aligns.append(curve)
+ self.straight_curve_lengs.append(curve.length())
+
+ return pnt_c2, pnt_ra2, Base.Straight(pnt_ad2, pnt_t1)
+
+ def _curve_low_high(self, pnt_center, pnt_1, dat1, dat2):
+ """ Return
+ """
+ # R1<R2
+ out_local = Base.cloth_local(dat1['radio'], dat1['a_out'])
+ in_local = Base.cloth_local(dat2['radio'], dat2['a_in'])
+
+ azi_in = pnt_center.azimuth(pnt_1)
+ alpha = dat2['dc_'] / dat2['radio']
+
+ if dat1['radio'] > 0 and dat2['radio'] > 0:
+ g90 = math.pi / 2
+ elif dat1['radio'] < 0 and dat2['radio'] < 0:
+ g90 = -math.pi / 2
+ else:
+ raise ValueError("Error: For change the radio sing a straight \
+ must be between the radios")
+ return None, None, None
+
+ pnt_t1 = pnt_center.project(abs(dat1['radio'] + out_local['y_o']),
+ azi_in + out_local['tau'])
+
+ pnt_t2 = pnt_t1.project(in_local['x_o'] - out_local['x_o'],
+ azi_in + out_local['tau'] + g90)
+
+ pnt_da1 = pnt_t1.project(out_local['x_o'], azi_in + out_local['tau'] +
+ g90)
+
+ pnt_c2 = pnt_t2.project(abs(dat2['radio'] + in_local['y_o']),
+ azi_in + out_local['tau'] + 2 * g90)
+
+ pnt_ra2 = pnt_c2.project(abs(dat2['radio']), azi_in + out_local['tau']
+ - in_local['tau'] + alpha)
+
+ if dat1['a_out'] != 0:
+ cloth = Base.Clothoid(dat1['a_out'], dat1['radio'],
+ pnt_t1.azimuth(pnt_da1), 'out', None, pnt_c2)
+ self.list_aligns.append(cloth)
+ self.straight_curve_lengs.append(cloth.length())
+
+ curve = Base.Curve(dat2['radio'], alpha, pnt_c2.azimuth(pnt_ra2),
+ pnt_c2)
+ self.list_aligns.append(curve)
+ self.straight_curve_lengs.append(curve.length())
+
+ return pnt_c2, pnt_ra2, Base.Straight(pnt_t1, pnt_da1)
+
+ def _curve_straight(self, pnt_center, pnt_1, dat1, dat2):
+ """ Return
+ """
+ # R1 != 0 y R2 = 0
+ out_local = Base.cloth_local(dat1['radio'], dat1['a_out'])
+
+ azi_in = pnt_center.azimuth(pnt_1)
+ # pnt_ra = pnt_1
+
+ if dat1['radio'] > 0:
+ g90 = math.pi / 2
+ else:
+ g90 = -math.pi / 2
+
+ pnt_t1 = pnt_center.project(abs(dat1['radio'] + out_local['y_o']),
+ azi_in + out_local['tau'])
+
+ pnt_da = pnt_t1.project(out_local['x_o'], azi_in + out_local['tau'] +
+ g90)
+
+ azi_out = pnt_center.azimuth(pnt_t1) + g90
+
+ if dat1['a_out'] == 0:
+ # pnt_da = pnt_ra
+ pnt_da = pnt_1
+ else:
+ cloth = Base.Clothoid(dat1['a_out'], dat1['radio'], azi_out, 'out',
+ None, pnt_center)
+ self.list_aligns.append(cloth)
+ self.straight_curve_lengs.append(cloth.length())
+
+ pnt_out = pnt_da.project(dat2['lr_'], azi_in + out_local['tau'] +
+ g90)
+
+ recta = Base.Straight(pnt_da, pnt_out)
+ self.list_aligns.append(recta)
+ self.straight_curve_lengs.append(recta.length())
+
+ return pnt_da, pnt_out, Base.Straight(pnt_da, pnt_out)
+
+ def _staight_curve(self, pnt_center, pnt_1, dat1, dat2):
+ """ Return
+ """
+ # R1 = 0 y R2 != 0
+ in_local = Base.cloth_local(dat2['radio'], dat2['a_in'])
+
+ alpha = dat2['dc_'] / dat2['radio']
+
+ azi_in = pnt_center.azimuth(pnt_1)
+ pnt_ad = pnt_center.project(dat1['lr_'], azi_in)
+
+ pnt_t2 = pnt_ad.project(in_local['x_o'], azi_in)
+
+ if dat2['radio'] > 0:
+ g90 = math.pi / 2
+ else:
+ g90 = -math.pi / 2
+
+ pnt_c2 = pnt_t2.project(abs(dat2['radio'] + in_local['y_o']), azi_in +
+ g90)
+ pnt_c2.npk = dat1['lr_']
+
+ az_in_c = azi_in + in_local['tau'] - g90
+ if az_in_c < 0:
+ az_in_c += 2 * math.pi
+
+ pnt_ra = pnt_c2.project(abs(dat2['radio']),
+ az_in_c + alpha)
+ pnt_ra.npk = dat1['lr_']
+
+ if dat2['a_in'] != 0:
+ cloth = Base.Clothoid(dat2['a_in'], dat2['radio'], azi_in, 'in',
+ None, pnt_c2)
+ self.list_aligns.append(cloth)
+ self.straight_curve_lengs.append(cloth.length())
+
+ curve = Base.Curve(dat2['radio'], abs(alpha), az_in_c, pnt_c2)
+ self.list_aligns.append(curve)
+ self.straight_curve_lengs.append(curve.length())
+
+ return pnt_c2, pnt_ra, Base.Straight(pnt_center, pnt_ad)
+
+ def get_charact(self):
+ """ Return
+ """
+ list_pnt = []
+# list_pnt.append(self.list_aligns[0].get_roadpoint(0)[0])
+ for i, ali in enumerate(self.list_aligns):
+ pnt = ali.get_roadpoint(-1)[0]
+ pnt.npk = self.leng_accum[i + 1]
+ list_pnt.append(pnt)
+ return list_pnt
+
+ @time_func
+ def set_roadline(self, start, end, intr, intc):
+ """ Return
+ """
+ puntos = self.get_roadpnts(start, end, intr, intc)
+# pnts_char = self.get_charact_pnts2()
+ # Name lenght type param rgb
+ attrs = ['Central_Axis', self.length(), 'axis', 0, '255:0:0']
+ self.roadline = Base.RoadLine(puntos, attrs, 'Central_Axis')
+
+ def add_pks(self, list_pks):
+ """ Return
+ """
+ for pk in list_pks:
+ self.roadline.insert(self.get_roadpoint(pk))
+
+
+if __name__ == '__main__':
+ import doctest
+ doctest.testmod()
Property changes on: grass-addons/grass7/vector/v.civil/road_plant.py
___________________________________________________________________
Added: svn:mime-type
+ text/x-python
Added: svn:eol-style
+ native
Added: grass-addons/grass7/vector/v.civil/road_profiles.py
===================================================================
--- grass-addons/grass7/vector/v.civil/road_profiles.py (rev 0)
+++ grass-addons/grass7/vector/v.civil/road_profiles.py 2016-07-01 22:30:22 UTC (rev 68831)
@@ -0,0 +1,478 @@
+# -*- coding: utf-8 -*-
+"""
+Created on Thu Sep 11 00:29:15 2014
+
+ at author: meskal
+"""
+
+#
+# import pygrass modules
+#
+import math
+
+# import road_base as Base
+# from grass.pygrass.raster import RasterRow
+
+from grass.pygrass.vector.geometry import Point
+from grass.pygrass.gis.region import Region
+from grass.pygrass.vector.geometry import Line
+
+
+class LongProfile(object):
+ """ Return
+ """
+ def __init__(self, options, scale, offset='0,0'):
+ """ Return
+ """
+ opts = options.split(',')
+ self.mark_lon = float(opts[0])
+ self.mark_x_dist = int(opts[1])
+ self.mark_y_dist = int(opts[2])
+ self.dist_ejes_x = float(opts[3])
+ self.scale = float(scale)
+
+ reg = Region()
+ self.zero_x = int(reg.west) + int(offset.split(',')[0])
+ self.zero_y = int(reg.south) + int(offset.split(',')[1])
+
+ self.max_elev = 0
+ self.min_elev = 0
+ self.alt_y = 0
+
+ def set_maxmin(self, r_line):
+ """Return
+ """
+ max_z = max([r_pnt.z for r_pnt in r_line])
+ max_t = max([r_pnt.terr for r_pnt in r_line])
+ min_z = min([r_pnt.z for r_pnt in r_line])
+ min_t = min([r_pnt.terr for r_pnt in r_line])
+
+ self.max_elev = math.ceil(max(max_z, max_t))
+ self.min_elev = math.floor(min(min_z, min_t))
+
+ self.alt_y = int((self.max_elev - self.min_elev) * self.scale +
+ self.zero_y)
+# if self.alt_y % int(self.mark_y_dist * self.scale) != 0:
+# self.alt_y += int(self.mark_y_dist * self.scale)
+
+ def _axis_y(self):
+ """Return
+ """
+ return [Line([Point(self.zero_x, self.zero_y),
+ Point(self.zero_x, self.alt_y)])], [['Axis Y', '', '']]
+
+ def _axis_x(self, r_line):
+ """Return
+ """
+ lines = []
+ for j in range(0, 4):
+ lines.append(Line([Point(self.zero_x,
+ self.zero_y - j * self.dist_ejes_x),
+ Point(self.zero_x + r_line[-1].npk,
+ self.zero_y - j * self.dist_ejes_x)]))
+ return lines, [['Axis X', '', ''], ['Elevation', '', ''],
+ ['Terrain', '', ''], ['Red elevation', '', '']]
+
+ def get_axes(self, puntos):
+ """Return
+ """
+ prof_axes, prof_axes_attrs = self._axis_y()
+ prof_axes_x, prof_axes_attrs_x = self._axis_x(puntos)
+ prof_axes.extend(prof_axes_x)
+ prof_axes_attrs.extend(prof_axes_attrs_x)
+
+ return prof_axes, prof_axes_attrs
+
+ def _axis_y_marks(self):
+ """Return
+ """
+ mark_y = []
+ labels = []
+ lim_sup = self.alt_y
+ if lim_sup % int(self.mark_y_dist * self.scale) != 0:
+ lim_sup += int(self.mark_y_dist * self.scale)
+ for i in range(self.zero_y, lim_sup, int(self.mark_y_dist *
+ self.scale)):
+ # labels.append(self.min_elev + i / self.scale)
+ labels.append(self.min_elev + (i - self.zero_y) / self.scale)
+ mark_y.append(Line([Point(self.zero_x - self.mark_lon, i),
+ Point(self.zero_x + self.mark_lon, i)]))
+ return mark_y, labels
+
+ def _axis_x_marks(self, r_line):
+ """Return
+ """
+ lim_sup = int(r_line[-1].npk)
+ if lim_sup % self.mark_x_dist != 0:
+ lim_sup += self.mark_x_dist
+ rang = range(0, lim_sup, self.mark_x_dist)
+
+ label_npk, label_z, label_terr, label_cotaroja = [], [], [], []
+ for r_pnt in r_line:
+ if r_pnt.npk in rang:
+ # pnts_marks.append(r_pnt)
+ label_npk.append(r_pnt.npk)
+ label_z.append(round(r_pnt.z, 4))
+ label_terr.append(round(r_pnt.terr, 4))
+ label_cotaroja.append(round(r_pnt.z - r_pnt.terr, 4))
+ label_npk.append(int(r_line[-1].npk))
+ label_z.append(r_line[-1].z)
+ label_terr.append(r_line[-1].terr)
+ label_cotaroja.append(r_line[-1].z - r_line[-1].terr)
+ labels_lines = label_npk + label_z + label_terr + label_cotaroja
+
+ rang = range(self.zero_x, self.zero_x + lim_sup, self.mark_x_dist)
+
+ lines = []
+ for j in range(0, 4):
+ mark_x = []
+ for i in rang:
+ mark_x.append(Line([
+ Point(i, self.zero_y - self.mark_lon - j *
+ self.dist_ejes_x),
+ Point(i, self.zero_y + self.mark_lon - j *
+ self.dist_ejes_x)]))
+ lines.extend(mark_x)
+
+ return lines, labels_lines
+
+ def get_axes_marks(self, puntos):
+ """Return
+ """
+ prof_ticks, prof_ticks_attrs = self._axis_y_marks()
+ prof_ticks_x, prof_ticks_attrs_x = self._axis_x_marks(puntos)
+ prof_ticks.extend(prof_ticks_x)
+ prof_ticks_attrs.extend(prof_ticks_attrs_x)
+ prof_ticks_attrs = [[str(tick)] for tick in prof_ticks_attrs]
+ return prof_ticks, prof_ticks_attrs
+
+ def _ras_segments(self, vert_segs):
+ """Return
+ """
+ lines = []
+ for r_line in vert_segs:
+
+ lines.append(self._ras(r_line))
+ return lines
+
+ def _ras(self, r_line):
+ """Return(self.max_elev - self.min_elev)
+ """
+ line = []
+ for r_pnt in r_line:
+ line.append(Point(r_pnt.npk + self.zero_x,
+ (r_pnt.z - self.min_elev) * self.scale +
+ self.zero_y))
+ return Line(line)
+
+ def _terr(self, r_line):
+ """Return
+ """
+ line = []
+ for r_pnt in r_line:
+ line.append(Point(r_pnt.npk + self.zero_x,
+ (r_pnt.terr - self.min_elev) * self.scale +
+ self.zero_y))
+ return Line(line)
+
+ def get_ras_terr(self, puntos, vert):
+ """Return
+ """
+ vert_segs, vert_attrs = vert.get_segments_pnts(puntos)
+ prof_segs = self._ras_segments(vert_segs)
+
+ prof_terr = self._terr(puntos)
+ prof_terr_attrs = ['0+000.0', 'Terrain', '0', '0', '']
+ prof_segs.append(prof_terr)
+ vert_attrs.append(prof_terr_attrs)
+
+ return prof_segs, vert_attrs
+
+ def charact_pnts(self, vert):
+ """Return
+ """
+ char_r_pnts, char_r_pnts_attrs = vert.get_charact_pnts()
+ list_r_pnts = []
+ for r_pnt in char_r_pnts:
+ list_r_pnts.append(Point(r_pnt.npk + self.zero_x,
+ (r_pnt.z - self.min_elev) * self.scale +
+ self.zero_y))
+ return list_r_pnts, char_r_pnts_attrs
+
+
+class TransProfiles(object):
+ """ Return
+ """
+ def __init__(self, options1, options2, scale, offset='0,0'):
+ """ Return
+ """
+ self.opts1 = dict(zip(['mark_lon', 'mark_x_dist', 'mark_y_dist'],
+ [int(opt) for opt in options1.split(',')]))
+
+ self.opts2 = dict(zip(['rows', 'dist_axis_x', 'dist_axis_y'],
+ [int(opt) for opt in options2.split(',')]))
+
+ self.scale = float(scale)
+
+ self.cols = 0
+ reg = Region()
+ self.zero_x = int(reg.west) + int(offset.split(',')[0])
+ self.zero_y = int(reg.south) + int(offset.split(',')[1])
+
+ self.mat_trans = []
+
+ self.rows_height = []
+ self.cols_width_left = [0]
+ self.cols_width_right = [0]
+
+ self.centers = []
+
+ def set_maxmin(self, trans, terr):
+ """Return
+ """
+ self.cols = int(math.ceil(len(trans) / self.opts2['rows']))
+ step = 0
+ maxtix = []
+ for i in range(self.cols):
+ row = []
+ for j in range(self.opts2['rows']):
+ trans[step].set_terr_pnts(terr)
+ row.append(trans[step])
+ step = step + 1
+ maxtix.append(row)
+
+ transp = [[row1[i] for row1 in maxtix] for i in range(len(maxtix[0]))]
+ for row in maxtix:
+ max_col_left = math.ceil(max([tran.max_left_width()
+ for tran in row]))
+ max_col_right = math.ceil(max([tran.max_right_width()
+ for tran in row]))
+ if max_col_left % self.opts1['mark_x_dist']:
+ max_col_left += self.opts1['mark_x_dist']
+ max_col_left -= max_col_left % self.opts1['mark_x_dist']
+ if max_col_right % self.opts1['mark_x_dist']:
+ max_col_right += self.opts1['mark_x_dist']
+ max_col_right -= max_col_right % self.opts1['mark_x_dist']
+
+ self.cols_width_left.append(max_col_left)
+ self.cols_width_right.append(max_col_right)
+
+ for row in transp:
+
+ difer = [tran.max_height() - tran.min_height() for tran in row]
+ max_height = max(difer) * self.scale
+ lim_sup = max([self._get_trans_lim_sup(tran) for tran in row])
+ self.rows_height.append(max([max_height, lim_sup]))
+
+ total_height = sum(self.rows_height) + (self.opts2['dist_axis_y'] *
+ self.opts2['rows'])
+ self.zero_y += total_height
+ self.mat_trans = maxtix
+
+ def set_centers(self):
+ """Return
+ """
+ orig_x = self.zero_x
+ for i in range(self.cols):
+ orig_x += self.cols_width_left[i] + self.cols_width_right[i]
+ row = []
+ orig_y = self.zero_y
+ for j in range(self.opts2['rows']):
+ orig_y -= self.rows_height[j] + self.opts2['dist_axis_y']
+ row.append(Point(orig_x, orig_y))
+ orig_x += self.opts2['dist_axis_x']
+ self.centers.append(row)
+
+ def _get_trans_lim_sup(self, trans):
+ """Return
+ """
+ lim_sup = ((trans.max_height() - trans.min_height()) * self.scale)
+
+ if lim_sup % int(self.opts1['mark_y_dist'] * self.scale) != 0:
+ lim_sup += int(self.opts1['mark_y_dist'] * self.scale)
+ lim_sup -= lim_sup % int(self.opts1['mark_y_dist'] * self.scale)
+ return lim_sup
+
+ def _axes_y(self):
+ """Return
+ """
+ list_lines = []
+ list_attrs = []
+ for i in range(self.cols):
+ for j in range(self.opts2['rows']):
+ lim_sup = self._get_trans_lim_sup(self.mat_trans[i][j])
+ pnt2 = Point(self.centers[i][j].x, self.centers[i][j].y +
+ lim_sup)
+ list_lines.append(Line([self.centers[i][j], pnt2]))
+ list_attrs.append(['Axis Y', '', ''])
+ return list_lines, list_attrs
+
+ def _axes_y_marks(self):
+ """Return
+ """
+ mark_y = []
+ labels = []
+
+ for i in range(self.cols):
+ for j in range(self.opts2['rows']):
+ lim_sup = self._get_trans_lim_sup(self.mat_trans[i][j])
+
+ for k in range(0, int(lim_sup) + 1,
+ int(self.opts1['mark_y_dist'] * self.scale)):
+
+ labels.append([self.mat_trans[i][j].min_height() + k /
+ self.scale])
+ mark_y.append(Line([Point(self.centers[i][j].x -
+ self.opts1['mark_lon'], k +
+ self.centers[i][j].y),
+ Point(self.centers[i][j].x +
+ self.opts1['mark_lon'], k +
+ self.centers[i][j].y)]))
+ return mark_y, labels
+
+ def _axes_x(self):
+ """Return
+ """
+ list_lines = []
+ list_attrs = []
+ for i in range(self.cols):
+ for j in range(self.opts2['rows']):
+ pnt2 = Point(self.centers[i][j].x +
+ self.cols_width_left[i + 1] +
+ self.cols_width_right[i + 1],
+ self.centers[i][j].y)
+ list_lines.append(Line([self.centers[i][j], pnt2]))
+ list_attrs.append(['Axis X', '', ''])
+ return list_lines, list_attrs
+
+ def _axes_x_marks(self):
+ """Return
+ """
+ mark_x = []
+ labels = []
+ for i in range(self.cols):
+ for j in range(self.opts2['rows']):
+
+ for k in range(int(self.cols_width_left[i + 1]), 0,
+ -int(self.opts1['mark_x_dist'])):
+ pnt1 = Point(self.centers[i][j].x +
+ self.cols_width_left[i + 1] - k,
+ self.centers[i][j].y - self.opts1['mark_lon'])
+ pnt2 = Point(self.centers[i][j].x +
+ self.cols_width_left[i + 1] - k,
+ self.centers[i][j].y + self.opts1['mark_lon'])
+ mark_x.append(Line([pnt1, pnt2]))
+ labels.append([-k])
+
+ pnt1 = Point(self.centers[i][j].x +
+ self.cols_width_left[i + 1],
+ self.centers[i][j].y - self.opts1['mark_lon'] - 1)
+ pnt2 = Point(self.centers[i][j].x +
+ self.cols_width_left[i + 1],
+ self.centers[i][j].y + self.opts1['mark_lon'] + 1)
+ mark_x.append(Line([pnt1, pnt2]))
+ labels.append([0])
+
+ for k in range(int(self.opts1['mark_x_dist']),
+ int(self.cols_width_right[i + 1]) + 1,
+ int(self.opts1['mark_x_dist'])):
+ pnt1 = Point(self.centers[i][j].x +
+ self.cols_width_left[i + 1] + k,
+ self.centers[i][j].y - self.opts1['mark_lon'])
+ pnt2 = Point(self.centers[i][j].x +
+ self.cols_width_left[i + 1] + k,
+ self.centers[i][j].y + self.opts1['mark_lon'])
+ mark_x.append(Line([pnt1, pnt2]))
+ labels.append([k])
+
+ return mark_x, labels
+
+ def get_axes(self):
+ """Return
+ """
+ axes, axes_attrs = self._axes_y()
+ axes_x, axes_x_attrs = self._axes_x()
+ axes.extend(axes_x)
+ axes_attrs.extend(axes_x_attrs)
+
+ return axes, axes_attrs
+
+ def get_axes_marks(self):
+ """Return
+ """
+ prof_ticks, prof_ticks_attrs = self._axes_y_marks()
+ prof_ticks_x, prof_ticks_attrs_x = self._axes_x_marks()
+ prof_ticks.extend(prof_ticks_x)
+ prof_ticks_attrs.extend(prof_ticks_attrs_x)
+
+ return prof_ticks, prof_ticks_attrs
+
+ def _ras(self):
+ """Return
+ """
+ list_lines = []
+ list_attrs = []
+ for i, col in enumerate(self.mat_trans):
+ for j, tran in enumerate(col):
+ line = []
+ for r_pnt in tran.get_ras_pnts():
+ diff = self.cols_width_left[i + 1] - tran.max_left_width()
+ line.append(Point(r_pnt.npk + self.centers[i][j].x + diff,
+ (r_pnt.z - tran.min_height()) *
+ self.scale + self.centers[i][j].y))
+ list_lines.append(Line(line))
+ list_attrs.append([tran.r_pnt.npk, 'Ras', tran.length(), '',
+ '0:0:255'])
+ return list_lines, list_attrs
+
+ def ras_pnts(self):
+ """Return
+ """
+ list_pnts = []
+ list_attrs = []
+ for i, col in enumerate(self.mat_trans):
+ for j, tran in enumerate(col):
+ for r_pnt in tran.get_ras_pnts():
+
+ diff = self.cols_width_left[i + 1] - tran.max_left_width()
+ list_pnts.append(Point(r_pnt.npk + self.centers[i][j].x +
+ diff,
+ (r_pnt.z - tran.min_height()) *
+ self.scale +
+ self.centers[i][j].y))
+ list_attrs.append([r_pnt.dist_displ, round(r_pnt.z, 4),
+ round(r_pnt.z - tran.r_pnt.z, 4)])
+
+ return list_pnts, list_attrs
+
+ def _terr(self):
+ """Return
+ """
+ list_lines = []
+ list_attrs = []
+ for i, col in enumerate(self.mat_trans):
+ for j, tran in enumerate(col):
+ line = []
+ for r_pnt in tran.terr_pnts:
+ diff = self.cols_width_left[i + 1] - tran.max_left_width()
+ line.append(Point(r_pnt.npk + self.centers[i][j].x + diff,
+ (r_pnt.terr - tran.min_height()) *
+ self.scale + self.centers[i][j].y))
+ list_lines.append(Line(line))
+ list_attrs.append([tran.r_pnt.npk, 'Terr', tran.length(), '',
+ '166:75:45'])
+ return list_lines, list_attrs
+
+ def get_ras_terr(self):
+ """Return
+ """
+ ras, ras_attrs = self._ras()
+ ras_terr, ras_terr_attrs = self._terr()
+ ras.extend(ras_terr)
+ ras_attrs.extend(ras_terr_attrs)
+
+ return ras, ras_attrs
+
+if __name__ == '__main__':
+ import doctest
+ doctest.testmod()
Property changes on: grass-addons/grass7/vector/v.civil/road_profiles.py
___________________________________________________________________
Added: svn:mime-type
+ text/x-python
Added: svn:eol-style
+ native
Added: grass-addons/grass7/vector/v.civil/road_road.py
===================================================================
--- grass-addons/grass7/vector/v.civil/road_road.py (rev 0)
+++ grass-addons/grass7/vector/v.civil/road_road.py 2016-07-01 22:30:22 UTC (rev 68831)
@@ -0,0 +1,342 @@
+# -*- coding: utf-8 -*-
+"""
+Created on Tue Sep 23 11:34:58 2014
+
+ at author: meskal
+"""
+
+# import math
+import time
+# import grass.script as grass
+from grass.pygrass.vector import VectorTopo
+
+# from grass.pygrass.vector.table import Link
+
+# import road_base as Base
+import road_plant as Plant
+import road_vertical as Vert
+import road_displ as Displ
+import road_trans as Trans
+import road_terr as Terr
+import road_tables as Tables
+import road_profiles as Profile
+import road_marks as Marks
+# import road_topotools as Topotools
+
+
+def time_func(funcion_f):
+ """Return
+ """
+ def funcion_r(*arg):
+ """Return
+ """
+ t_1 = time.clock()
+ res = funcion_f(*arg)
+ t_2 = time.clock()
+ print('%s tarda %0.5f ms' % (funcion_f.__name__, (t_2 - t_1) * 1000.0))
+ return res
+ return funcion_r
+
+
+# =============================================
+# PLANT
+# =============================================
+
+
+class Road(object):
+ """Instantiate a new road with a polygon map and instantiate. For run
+ doctest you must to execute the example backup in the documentation
+ >>> import road_road as Road
+ >>> road = Road.Road('Circuit')
+ >>> road
+ Circuit
+ """
+ def __init__(self, mapa=None):
+
+ self.mapa = mapa.split('@')[0]
+
+ self.polygon = VectorTopo(self.mapa)
+
+# super(Road, self).__init__(self.mapa, self.polygon)
+ self.rtab = Tables.RoadTables(self.mapa, self.polygon)
+
+
+ self.plant = None
+ self.vert = None
+ self.displ = None
+ self.trans = None
+ self.terr = None
+ self.taludes = None
+ self.long_prof = None
+ self.trans_prof = None
+ self.marks = None
+
+ def __str__(self):
+ return str(self.mapa)
+
+ def __repr__(self):
+ return str(self.mapa)
+
+ @time_func
+ def plant_generate(self, table_to_plant=False, bombeo=0):
+ """Set plant.
+ """
+ tabla = self.rtab.tables['_Plan']
+
+ if table_to_plant:
+ self.plant = Plant.Plant(self.rtab.polyline, tabla,
+ table_to_plan=True, bombeo=bombeo)
+ self.rtab.tables['first'].rewrite_obj(
+ self.plant.polygon, self.rtab.tables['first'].rows[0])
+ else:
+ self.plant = Plant.Plant(self.rtab.polyline, tabla,
+ table_to_plan=False, bombeo=bombeo)
+ tabla.update_plan_dists(self.plant)
+
+# self.update_tables_pnts(self.plant)
+
+ def plant_write(self):
+ """Write axis road
+ """
+ map_out = self.mapa + Tables.OUT_TABLES_NAMES['__Plant']
+
+ objs, values = self.plant.get_segments_pnts(self.plant.roadline,
+ self.vert, line=True)
+ self.rtab.new_map(map_out, 1, '__Plant', objs, values)
+# self.vert.set_lines_elev(segs)
+
+ objs, values = self.plant.get_charact_pnts(lines=False)
+ self.rtab.new_map(map_out, 2, '__Plant_PC', objs, values)
+
+ objs, values = self.plant.get_curves_centers()
+ self.rtab.new_map(map_out, 3, '__Plant_C', objs, values)
+
+ @time_func
+ def elev_generate(self):
+ """ Return
+ """
+ tabla = self.rtab.tables['_Vert']
+ self.vert = Vert.Vert(self.rtab.polyline, tabla, self.plant)
+
+ def elev_write(self):
+ """ Return
+ """
+ map_out = self.mapa + Tables.OUT_TABLES_NAMES['__Vertical']
+
+ objs, values = self.vert.get_segments_pnts(self.plant.roadline,
+ line=True)
+ self.rtab.new_map(map_out, 1, '__Vertical', objs, values)
+
+ objs, values = self.vert.get_charact_pnts()
+ self.rtab.new_map(map_out, 2, '__Vertical_PC', objs, values)
+
+ @time_func
+ def displ_generate(self, tab_subname=''):
+ """ Return
+ """
+ tabla = self.rtab.tables['_Displ' + tab_subname]
+ self.displ = Displ.Displaced(self.polygon, tabla, self.plant)
+
+ def displ_write(self, tab_subname=''):
+ """ Return
+ """
+ map_out = self.mapa + Tables.OUT_TABLES_NAMES['__Displaced'] + \
+ tab_subname
+
+ objs, values = self.displ.get_lines()
+ self.rtab.new_map(map_out, 1, '__Displaced', objs, values, tab_subname)
+
+ objs, values = self.displ.get_charact()
+ self.rtab.new_map(map_out, 2, '__Displaced_PC', objs, values,
+ tab_subname)
+
+ def displ_areas_write(self, opts, tab_subname=''):
+ """ Return
+ """
+ tab_sufix = '__Displaced_Areas'
+ map_out = self.mapa + tab_sufix + tab_subname
+
+ objs, values = self.displ.get_areas(opts)
+ self.rtab.new_map(map_out, 1, tab_sufix, objs, values, tab_subname)
+
+ @time_func
+ def terr_generate(self, dem_map):
+ """ Return
+ """
+ self.terr = Terr.Terrain(dem_map)
+
+ @time_func
+ def trans_generate(self):
+ """ Return
+ """
+ tabla = self.rtab.tables['_Trans']
+ self.trans = Trans.Trans(self.polygon, tabla, self.plant, self.vert,
+ self.terr)
+
+ def trans_write_pks(self, startend, opts):
+ """ Return
+ """
+ map_out = self.mapa + Tables.OUT_TABLES_NAMES['__Pks']
+
+ objs, values = self.trans.generate_pks(startend[0], startend[1],
+ opts[0], opts[1], opts[2],
+ opts[3])
+ self.rtab.new_map(map_out, 1, '__Pks', objs, values)
+
+ def trans_write(self):
+ """ Return
+ """
+ map_out = self.mapa + Tables.OUT_TABLES_NAMES['__Trans']
+
+ objs, values = self.trans.get_trans()
+ self.rtab.new_map(map_out, 1, '__Trans', objs, values)
+
+ objs, values = self.trans.get_pnts_trans(self.displ)
+ self.rtab.new_map(map_out, 2, '__Trans_PC', objs, values)
+
+ objs, values = self.trans.get_pnts_trans_terr(self.displ, self.taludes,
+ self.terr)
+ self.rtab.new_map(map_out, 3, '__Trans_PT', objs, values)
+
+ @time_func
+ def taludes_generate(self):
+ """ Return
+ """
+ tabla = self.rtab.tables['_Terr']
+ self.taludes = Terr.Taludes(self.polygon, tabla, self.terr)
+
+ def taludes_write(self):
+ """ Return
+ """
+ map_out = self.mapa + Tables.OUT_TABLES_NAMES['__Slopes']
+
+ objs, values = self.taludes.get_lines()
+ self.rtab.new_map(map_out, 1, '__Slopes', objs, values)
+
+ def taludes_areas_write(self):
+ """ Return
+ """
+ map_out = self.mapa + Tables.OUT_TABLES_NAMES['__Slopes_Areas']
+
+ objs, values = self.taludes.get_areas(self.displ)
+ self.rtab.new_map(map_out, 1, '__Slopes_Areas', objs, values)
+
+ @time_func
+ def long_profile_generate(self, options, scale, offset):
+ """Return
+ """
+ self.long_prof = Profile.LongProfile(options, scale, offset)
+
+ def long_profile_write(self):
+ """ Return
+ """
+ map_out = self.mapa + Tables.OUT_TABLES_NAMES['__LongProfile']
+
+# self.terr.set_pnts_terr(puntos)
+ self.long_prof.set_maxmin(self.plant.roadline)
+
+ objs, vals = self.long_prof.get_ras_terr(self.plant.roadline,
+ self.vert)
+ self.rtab.new_map(map_out, 1, '__LongProfile', objs, vals)
+
+ objs, vals = self.long_prof.charact_pnts(self.vert)
+ self.rtab.new_map(map_out, 2, '__LProfile_PC', objs, vals)
+
+ objs, vals = self.long_prof.get_axes(self.plant.roadline)
+ self.rtab.new_map(map_out, 3, '__LProfile_Axis', objs, vals)
+
+ objs, vals = self.long_prof.get_axes_marks(self.plant.roadline)
+ self.rtab.new_map(map_out, 4, '__LProfile_Ticks', objs, vals)
+
+ @time_func
+ def trans_profiles_generate(self, options1, options2, scale, offset):
+ """Return
+ """
+ self.trans_prof = Profile.TransProfiles(options1, options2, scale)
+
+ def trans_profiles_write(self):
+ """ Return
+ """
+ map_out = self.mapa + Tables.OUT_TABLES_NAMES['__TransProfiles']
+
+ if len(self.trans) == 0:
+ return None
+
+ self.trans_prof.set_maxmin(self.trans, self.terr)
+ self.trans_prof.set_centers()
+
+ objs, vals = self.trans_prof.get_ras_terr()
+ self.rtab.new_map(map_out, 1, '__TransProfiles', objs, vals)
+
+ objs, vals = self.trans_prof.ras_pnts()
+ self.rtab.new_map(map_out, 2, '__TProfile_PC', objs, vals)
+
+ objs, vals = self.trans_prof.get_axes()
+ self.rtab.new_map(map_out, 3, '__TProfile_Axis', objs, vals)
+
+ objs, vals = self.trans_prof.get_axes_marks()
+ self.rtab.new_map(map_out, 4, '__TProfile_Ticks', objs, vals)
+
+ @time_func
+ def marks_generate(self, tab_subname=''):
+ """ Return
+ """
+ tabla = self.rtab.tables['_Marks' + tab_subname]
+ self.marks = Marks.Marks(self.polygon, tabla, self.plant, self.vert)
+
+ def marks_write(self, tab_subname=''):
+ """ Return
+ """
+ tab_sufix = '__Marks'
+ map_out = self.mapa + Tables.OUT_TABLES_NAMES['__Marks'] + tab_subname
+
+ objs, values = self.marks.get_pnts()
+ self.rtab.new_map(map_out, 1, tab_sufix, objs, values, tab_subname)
+
+ def tri_write(self):
+ """ Return
+ """
+ map_out = self.mapa + Tables.OUT_TABLES_NAMES['__Topo']
+
+ objs, values = self.plant.roadline.get_pnts_attrs()
+
+ for displ in self.displ.displines:
+ objs2, values2 = displ.roadline.get_pnts_attrs()
+ for i, obj in enumerate(objs2):
+ values2[i][0] = obj.acum_pk
+
+ objs.extend(objs2)
+ values.extend(values2)
+
+ for r_line in self.taludes.talud_left.roadlines:
+ objs2, values2 = r_line.get_pnts_attrs()
+ objs.extend(objs2)
+ values.extend(values2)
+
+ for r_line in self.taludes.talud_right.roadlines:
+ objs2, values2 = r_line.get_pnts_attrs()
+ objs.extend(objs2)
+ values.extend(values2)
+
+ self.rtab.new_map(map_out, 1, '__Topo', objs, values)
+
+ objs, values = self.plant.roadline.get_line_attrs()
+
+ objs2, values2 = self.displ.get_lines()
+ objs.extend(objs2)
+ values.extend(values2)
+
+ objs2, values2 = self.taludes.get_lines()
+ objs.extend(objs2)
+ values.extend(values2)
+
+ self.rtab.new_map(map_out, 2, '__Topo_BreakLines', objs, values)
+
+ map_out = self.mapa + Tables.OUT_TABLES_NAMES['__Topo_Hull']
+ objs, values = self.taludes.get_hull(self.displ)
+ self.rtab.new_map(map_out, 1, '__Topo_Hull', objs, values)
+
+
+if __name__ == '__main__':
+ import doctest
+ doctest.testmod()
Property changes on: grass-addons/grass7/vector/v.civil/road_road.py
___________________________________________________________________
Added: svn:mime-type
+ text/x-python
Added: svn:eol-style
+ native
Added: grass-addons/grass7/vector/v.civil/road_tables.py
===================================================================
--- grass-addons/grass7/vector/v.civil/road_tables.py (rev 0)
+++ grass-addons/grass7/vector/v.civil/road_tables.py 2016-07-01 22:30:22 UTC (rev 68831)
@@ -0,0 +1,933 @@
+# -*- coding: utf-8 -*-
+"""
+Created on Thu Oct 2 18:24:22 2014
+
+ at author: meskal
+"""
+
+# from grass.pygrass.vector.table import Link
+import time
+import grass.script as grass
+from grass.pygrass.vector.geometry import Point
+from grass.pygrass.vector import sql
+from grass.pygrass.vector.table import Link
+from grass.pygrass.vector import VectorTopo
+
+# from grass.pygrass.vector.geometry import Line
+
+
+def time_func(funcion_f):
+ """Return
+ """
+ def funcion_r(*arg):
+ """Return
+ """
+ t_1 = time.clock()
+ res = funcion_f(*arg)
+ t_2 = time.clock()
+ print('%s tarda %0.5f ms' % (funcion_f.__name__, (t_2 - t_1) * 1000.0))
+ return res
+ return funcion_r
+
+# =============================================
+# PLANT
+# =============================================
+
+# TABLES_NAMES
+TABLES_NAMES = ('first', '_Plan', '_Vert', '_Displ', '_Terr', '_Trans',
+ '_Marks')
+
+# OUT_TABLES_NAMES
+OUT_TABLES_NAMES = {'__Plant': '__Plant',
+ '__Plant_PC': '__Plant_PC',
+ '__Plant_C': '__Plant_C',
+ '__Vertical': '__Vertical',
+ '__Vertical_PC': '__Vertical_PC',
+ '__Displaced': '__Displaced',
+ '__Displaced_PC': '__Displaced_PC',
+ '__Displaced_Areas': '__Displaced_Areas',
+ '__Pks': '__Pks',
+ '__Trans': '__Trans',
+ '__Trans_PC': '__Trans_PC',
+ '__Trans_PT': '__Trans_PT',
+ '__Slopes': '__Slopes',
+ '__Marks': '__Marks',
+ '__Slopes_Areas': '__Slopes_Areas',
+ '__LongProfile': '__LongProfile',
+ '__LProfile_PC': '__LProfile_PC',
+ '__LProfile_Axis': '__LProfile_Axis',
+ '__LProfile_Ticks': '__LProfile_Ticks',
+ '__TransProfiles': '__TransProfiles',
+ '__TProfile_PC': '__TProfile_PC',
+ '__TProfile_Axis': '__TProfile_Axis',
+ '__TProfile_Ticks': '__TProfile_Ticks',
+ '__Topo': '__Topo',
+ '__Topo_BreakLines': '__Topo_BreakLines',
+ '__Topo_Hull': '__Topo_Hull'}
+
+# TABLES
+TABLES = {
+
+ 'first': [(u'cat', u'INTEGER PRIMARY KEY'),
+ (u'name', u'TEXT')],
+
+ '_Plan': [(u'cat2', u'INTEGER PRIMARY KEY'),
+ (u'pk_eje', u'DOUBLE PRECISION'),
+ (u'radio', u'DOUBLE PRECISION'),
+ (u'a_in', u'DOUBLE PRECISION'),
+ (u'a_out', u'DOUBLE PRECISION'),
+ (u'widening', u'DOUBLE PRECISION'),
+ (u'superelev', u'TEXT'),
+ (u'dc_', u'DOUBLE PRECISION'),
+ (u'lr_', u'DOUBLE PRECISION')],
+
+ '_Vert': [(u'cat3', u'INTEGER PRIMARY KEY'),
+ (u'pk', u'DOUBLE PRECISION'),
+ (u'elev', u'DOUBLE PRECISION'),
+ (u'kv', u'DOUBLE PRECISION'),
+ (u'l', u'DOUBLE PRECISION'),
+ (u'b', u'DOUBLE PRECISION')],
+
+ '_Displ': [(u'cat4', u'INTEGER PRIMARY KEY'),
+ (u'pk', u'DOUBLE PRECISION'),
+ (u'sec_left', u'TEXT'),
+ (u'sec_right', u'TEXT'),
+ (u'type_left', u'TEXT'),
+ (u'type_right', u'TEXT')],
+
+ '_Terr': [(u'cat5', u'INTEGER PRIMARY KEY'),
+ (u'pk', u'DOUBLE PRECISION'),
+ (u'cut_left', u'DOUBLE PRECISION'),
+ (u'cut_right', u'DOUBLE PRECISION'),
+ (u'fill_left', u'DOUBLE PRECISION'),
+ (u'fill_right', u'DOUBLE PRECISION'),
+ (u'height', u'DOUBLE PRECISION'),
+ (u'leng', u'DOUBLE PRECISION')],
+
+ '_Trans': [(u'cat6', u'INTEGER PRIMARY KEY'),
+ (u'pk', u'DOUBLE PRECISION'),
+ (u'dist_left', u'DOUBLE PRECISION'),
+ (u'dist_right', u'DOUBLE PRECISION'),
+ (u'npk', u'DOUBLE PRECISION')],
+
+ '_Marks': [(u'cat7', u'INTEGER PRIMARY KEY'),
+ (u'pk', u'DOUBLE PRECISION'),
+ (u'dist', u'TEXT'),
+ (u'elev', u'TEXT'),
+ (u'azi', u'TEXT'),
+ (u'name', u'TEXT'),
+ (u'cod', u'TEXT')]
+}
+
+
+OUT_TABLES = {
+ # Plant
+ '__Plant': [(u'cat', u'INTEGER PRIMARY KEY'),
+ (u'pk', u'TEXT'),
+ (u'type', u'TEXT'),
+ (u'long', u'DOUBLE PRECISION'),
+ (u'param', u'TEXT'),
+ (u'GRASSRGB', u'TEXT')],
+
+ '__Plant_PC': [(u'cat2', u'INTEGER PRIMARY KEY'),
+ (u'pk', u'TEXT'),
+ (u'azimut', u'DOUBLE PRECISION'),
+ (u'type', u'TEXT'),
+ (u'param', u'TEXT')],
+
+ '__Plant_C': [(u'cat3', u'INTEGER PRIMARY KEY'),
+ (u'param', u'TEXT')],
+
+ # Vertical
+ '__Vertical': [(u'cat', u'INTEGER PRIMARY KEY'),
+ (u'pk', u'TEXT'),
+ (u'type', u'TEXT'),
+ (u'long', u'DOUBLE PRECISION'),
+ (u'param', u'TEXT'),
+ (u'GRASSRGB', u'TEXT')],
+
+ '__Vertical_PC': [(u'cat2', u'INTEGER PRIMARY KEY'),
+ (u'pk', u'TEXT'),
+ (u'type', u'TEXT'),
+ (u'param', u'TEXT')],
+
+ # Displaced
+ '__Displaced': [(u'cat', u'INTEGER PRIMARY KEY'),
+ (u'name', u'TEXT'),
+ (u'long', u'DOUBLE PRECISION'),
+ (u'type', u'TEXT'),
+ (u'param', u'DOUBLE PRECISIO'),
+ (u'GRASSRGB', u'TEXT')],
+
+ '__Displaced_PC': [(u'cat2', u'INTEGER PRIMARY KEY'),
+ (u'pk', u'TEXT'),
+ (u'azimut', u'DOUBLE PRECISION'),
+ (u'type', u'TEXT'),
+ (u'param', u'TEXT'),
+ (u'displ', u'TEXT')],
+
+ '__Displaced_Areas': [(u'cat', u'INTEGER PRIMARY KEY'),
+ (u'num', u'TEXT')],
+ # Trans
+ '__Pks': [(u'cat', u'INTEGER PRIMARY KEY'),
+ (u'pk', u'TEXT'),
+ (u'azimut', u'DOUBLE PRECISION'),
+ (u'type', u'TEXT'),
+ (u'GRASSRGB', u'TEXT')],
+
+ '__Trans': [(u'cat', u'INTEGER PRIMARY KEY'),
+ (u'pk', u'TEXT'),
+ (u'azimut', u'DOUBLE PRECISION'),
+ (u'type', u'TEXT'),
+ (u'dist_left', u'DOUBLE PRECISION'),
+ (u'dist_right', u'DOUBLE PRECISION'),
+ (u'GRASSRGB', u'TEXT')],
+
+
+ '__Trans_PC': [(u'cat2', u'INTEGER PRIMARY KEY'),
+ (u'pk', u'TEXT'),
+ (u'azimut', u'DOUBLE PRECISION'),
+ (u'trans', u'TEXT'),
+ (u'param', u'TEXT'),
+ (u'type', u'TEXT')],
+
+ '__Trans_PT': [(u'cat3', u'INTEGER PRIMARY KEY'),
+ (u'pk', u'TEXT'),
+ (u'azimut', u'DOUBLE PRECISION'),
+ (u'trans', u'TEXT'),
+ (u'param', u'TEXT'),
+ (u'type', u'TEXT')],
+
+ # Taludes
+ '__Slopes': [(u'cat', u'INTEGER PRIMARY KEY'),
+ (u'name', u'TEXT'),
+ (u'long', u'DOUBLE PRECISION'),
+ (u'type', u'TEXT'),
+ (u'param', u'DOUBLE PRECISION'),
+ (u'GRASSRGB', u'TEXT')],
+
+ # Marks
+ '__Marks': [(u'cat', u'INTEGER PRIMARY KEY'),
+ (u'pk', u'TEXT'),
+ (u'azimut', u'DOUBLE PRECISION'),
+ (u'name', u'TEXT'),
+ (u'cod', u'TEXT'),
+ (u'dist', u'DOUBLE PRECISION'),
+ (u'elev', u'DOUBLE PRECISION')],
+
+ # Taludes
+ '__Slopes_Areas': [(u'cat', u'INTEGER PRIMARY KEY'),
+ (u'name', u'TEXT'),
+ (u'long', u'DOUBLE PRECISION'),
+ (u'type', u'TEXT'),
+ (u'param', u'TEXT'),
+ (u'GRASSRGB', u'TEXT')],
+
+ # LongProfile
+ '__LongProfile': [(u'cat', u'INTEGER PRIMARY KEY'),
+ (u'pk', u'TEXT'),
+ (u'type', u'TEXT'),
+ (u'long', u'DOUBLE PRECISION'),
+ (u'param', u'TEXT'),
+ (u'GRASSRGB', u'TEXT')],
+
+ '__LProfile_PC': [(u'cat2', u'INTEGER PRIMARY KEY'),
+ (u'pk', u'TEXT'),
+ (u'type', u'TEXT'),
+ (u'param', u'TEXT')],
+
+ '__LProfile_Axis': [(u'cat3', u'INTEGER PRIMARY KEY'),
+ (u'name', u'TEXT'),
+ (u'type', u'TEXT'),
+ (u'param', u'TEXT')],
+
+ '__LProfile_Ticks': [(u'cat4', u'INTEGER PRIMARY KEY'),
+ (u'param', u'TEXT')],
+
+ # TransProfiles
+ '__TransProfiles': [(u'cat', u'INTEGER PRIMARY KEY'),
+ (u'pk', u'TEXT'),
+ (u'type', u'TEXT'),
+ (u'long', u'DOUBLE PRECISION'),
+ (u'param', u'TEXT'),
+ (u'GRASSRGB', u'TEXT')],
+
+ '__TProfile_PC': [(u'cat2', u'INTEGER PRIMARY KEY'),
+ (u'dist', u'TEXT'),
+ (u'elev', u'TEXT'),
+ (u'rel_elev', u'TEXT')],
+
+ '__TProfile_Axis': [(u'cat3', u'INTEGER PRIMARY KEY'),
+ (u'name', u'TEXT'),
+ (u'type', u'TEXT'),
+ (u'param', u'TEXT')],
+
+ '__TProfile_Ticks': [(u'cat4', u'INTEGER PRIMARY KEY'),
+ (u'param', u'TEXT')],
+
+ # Tri
+ '__Topo': [(u'cat', u'INTEGER PRIMARY KEY'),
+ (u'pk', u'DOUBLE PRECISION'),
+ (u'name', u'TEXT'),
+ (u'azi', u'DOUBLE PRECISION'),
+ (u'p_type', u'TEXT'),
+ (u'align', u'INTEGER'),
+ (u'vparam', u'DOUBLE PRECISION'),
+ (u'v_type', u'TEXT'),
+ (u'terr', u'DOUBLE PRECISION'),
+ (u't_type', u'TEXT'),
+ (u'dist_d', u'DOUBLE PRECISION'),
+ (u'x', u'DOUBLE PRECISION'),
+ (u'y', u'DOUBLE PRECISION'),
+ (u'z', u'DOUBLE PRECISION'),
+ (u'action', u'TEXT')],
+
+ '__Topo_BreakLines': [(u'cat2', u'INTEGER PRIMARY KEY'),
+ (u'name', u'TEXT'),
+ (u'long', u'DOUBLE PRECISION'),
+ (u'type', u'TEXT'),
+ (u'param', u'DOUBLE PRECISION'),
+ (u'GRASSRGB', u'TEXT')],
+
+ '__Topo_Hull': [(u'cat', u'INTEGER PRIMARY KEY'),
+ (u'name', u'TEXT'),
+ (u'long', u'DOUBLE PRECISION')]
+}
+
+INIT_VALUES = {
+
+ 'first': ['name_road'],
+ '_Plan': [0, 0, 0, 0, 0, '', 0, 0],
+ '_Vert': [0, 0, 0, 0, 0],
+ '_Displ': [0, '', '', '', ''],
+ '_Trans': [0, 0, 0, 0],
+ '_Marks': [0, '', '', '', '', ''],
+ '_Terr': [0, 1, 1, 1, 1, 0, 0]
+}
+
+
+class RoadTable(object):
+ """ Return
+ """
+ def __init__(self, polygon, polyline, layer, map_name, tab_sufix):
+ """ Return
+ """
+ self.polygon = polygon
+ self.tab_name = map_name
+ self.name = tab_sufix
+# self.tab_sufix2 = tab_sufix2
+
+ self.polyline = polyline
+ self.layer = layer
+ self.cols_names = None
+ self.rows = None
+
+ self._init_table()
+
+ def __getitem__(self, index):
+ return dict(zip(self.cols_names, self.rows[index]))
+
+ def __setitem__(self, index, name, value):
+ ind = self.cols_names.index(name)
+ self.rows[index][ind] = value
+
+ def __delitem__(self, index):
+ del self.rows[index]
+
+ def __len__(self):
+ return len(self.rows)
+
+# @time_func
+ def _init_table(self):
+ """Return
+ """
+ link = self.polygon.dblinks.by_name(self.tab_name)
+
+ if link is None:
+ self.polygon.open('rw')
+ print('creating table')
+ self._create_table()
+ self.polygon.close()
+
+ self.polygon.open('rw', self.layer, with_z=True)
+ if self.name == '_Plan':
+ self._set_default(map_plant=True)
+ else:
+ self._set_default()
+ self.polygon.close()
+
+ self.polygon.open('r')
+ link = self.polygon.dblinks.by_name(self.tab_name)
+ self.layer = link.layer
+ self.cols_names = link.table().columns.names()
+ self.polygon.close()
+
+ self._check_columns()
+
+ self.polygon.open('r')
+ tabla_sql = "SELECT * FROM {name};".format(name=self.tab_name)
+ self.rows = link.table().execute(tabla_sql).fetchall()
+ self.rows = [list(row) for row in self.rows]
+ self.polygon.close()
+
+ def _create_table(self):
+ """Return
+ """
+ link = Link(self.layer, self.tab_name, self.tab_name,
+ 'cat' + str(self.layer))
+ self.polygon.dblinks.add(link)
+ table = link.table()
+
+ tab_sufix = self.name
+ if self.name == '':
+ tab_sufix = 'first'
+ TABLES[tab_sufix][0] = (u'cat' + str(self.layer),
+ u'INTEGER PRIMARY KEY')
+ if not table.exist():
+ table.create(TABLES[tab_sufix])
+ table.conn.commit()
+
+ def _set_default(self, map_plant=False):
+ """Return
+ """
+ tab_sufix = self.name
+ if self.name == '':
+ tab_sufix = 'first'
+ values = INIT_VALUES[tab_sufix]
+ self.polygon.write(self.polyline[0], cat=1, attrs=values)
+ self.polygon.table.conn.commit()
+ self.polygon._cats = []
+ return 0
+ values = INIT_VALUES[tab_sufix]
+ values[0] = 0
+ dist2 = self.polyline[0].distance(self.polyline[1])
+ if map_plant:
+ values[-1] = dist2
+
+ self.polygon.write(self.polyline[0], cat=1, attrs=values)
+ dist = dist2
+
+ ult_i = 1
+ for i in range(1, len(self.polyline[:-1])):
+
+ dist2 = self.polyline[i].distance(self.polyline[i + 1])
+ if map_plant:
+ values[-1] = dist2
+ values[0] = dist
+ ult_i = i + 1
+ self.polygon.write(self.polyline[i], i + 1, values)
+ dist += dist2
+
+ if map_plant:
+ values[-1] = 0
+ values[0] = dist
+
+ self.polygon.write(self.polyline[-1], ult_i + 1, values)
+ self.polygon.table.conn.commit()
+ self.polygon._cats = []
+
+ def get_column(self, name):
+ """Return
+ """
+ index = self.cols_names.index(name)
+ return [row[index] for row in self.rows]
+
+ def _check_columns(self):
+ """Return
+ """
+ cols_out = []
+ tab_sufix = self.name
+ if self.name == '':
+ tab_sufix = 'first'
+ for col in TABLES[tab_sufix][1:]:
+ if col[0] not in self.cols_names:
+ cols_out.append(col)
+ if cols_out != []:
+ grass.warning("adding columns " + ','.join([p[0] for p in
+ cols_out]))
+ self._add_columns(cols_out)
+
+ def _add_columns(self, columns):
+ """Return
+ """
+ self.polygon.open('rw')
+
+ table = self.polygon.dblinks.by_name(self.tab_name).table()
+
+ for col in columns:
+ table.execute(sql.ADD_COL.format(tname=self.tab_name, cname=col[0],
+ ctype=col[1]))
+ table.conn.commit()
+ self.polygon.close()
+
+# @time_func
+ def rewrite_obj(self, obj, attrs):
+ """Return
+ """
+ self.polygon.open('rw', self.layer, with_z=True)
+
+ if isinstance(obj, Point):
+ type_obj = 'points'
+ else:
+ type_obj = 'lines'
+
+ obj_org = self.polygon.cat(attrs[0], type_obj, self.layer)[0]
+
+ self.polygon.rewrite(obj_org, obj, attrs[1:])
+ self.polygon.table.conn.commit()
+ self.polygon.close()
+
+ def rewrite_new(self, obj, attrs, cat_ind):
+ """Return
+ """
+ self.polygon.open('rw', self.layer, with_z=True)
+
+ tabla_sql = "DELETE FROM " + self.tab_name + " WHERE cat" + \
+ str(self.layer) + "=" + str(attrs[0]) + ";"
+ self.polygon.table.execute(tabla_sql)
+
+ if isinstance(obj, Point):
+ type_obj = 'points'
+ else:
+ type_obj = 'lines'
+
+ obj_org = self.polygon.cat(attrs[0], type_obj, self.layer)
+
+ if obj_org:
+ obj_org = obj_org[0]
+ self.polygon.delete(obj_org.id)
+
+ self.polygon.write(obj, cat_ind, attrs[1:])
+
+ self.polygon.table.conn.commit()
+ self.polygon.close()
+
+ def _execute_update(self):
+ """Return
+ """
+ self.polygon.open('r')
+ tabla = self.polygon.dblinks.by_name(self.tab_name).table()
+
+ for row in self.rows:
+ vals = ','.join(["%s='%s'" % (k, v) for k, v in
+ zip(self.cols_names[1:], row[1:])])
+ cond = "%s=%s" % (self.cols_names[0], row[0])
+
+ sql1 = "UPDATE {tname} SET {values} WHERE {condition};"
+ tabla_sql = sql1.format(tname=self.tab_name, values=vals,
+ condition=cond)
+ tabla.execute(tabla_sql)
+ tabla.conn.commit()
+ self.polygon.close()
+
+ def update_plan_dists(self, plant):
+ """Return
+ """
+ num = 0
+ for i in range(0, len(plant.straight_curve_lengs[:-1]), 2):
+ index = self.cols_names.index('dc_')
+ self.rows[num][index] = plant.straight_curve_lengs[i]
+ index = self.cols_names.index('lr_')
+ self.rows[num][index] = plant.straight_curve_lengs[i + 1]
+ num += 1
+ self._execute_update()
+
+# def write_obj(self, objs, values):
+# """Return
+# """
+# self.polygon.open('rw', self.layer, with_z=True,
+# tab_name=self.tab_name, tab_cols=self.cols_names)
+# for obj, val in (objs, values):
+# self.polygon.write(obj, val)
+# self.polygon.table.conn.commit()
+# self.polygon.close()
+
+ def displ_add_del_col(self, num_col, side, values, add):
+ """Return
+ """
+ num_col = int(num_col)
+ values = values.split(';')
+ if side == 'left':
+ name_sec = 'sec_left'
+ type_sec = 'type_left'
+ elif side == 'right':
+ name_sec = 'sec_right'
+ type_sec = 'type_right'
+
+ self._displ_check_type_col(name_sec, type_sec)
+
+ ind = self.cols_names.index(name_sec)
+ ind2 = self.cols_names.index(type_sec)
+ self.rows[0][ind] = self._displ_add_del_sec(self[0][name_sec], num_col,
+ values[0], side, add)
+ self.rows[0][ind2] = self._displ_add_del_sec(self[0][type_sec],
+ num_col, 'l', side, add)
+
+ self.rows[-1][ind] = self._displ_add_del_sec(self[-1][name_sec],
+ num_col, values[1], side,
+ add)
+ self.rows[-1][ind2] = self._displ_add_del_sec(self[-1][type_sec],
+ num_col, 'l', side, add)
+ for i in range(1, len(self.rows) - 1):
+ self.rows[i][ind] = self._displ_add_del_sec(self[i][name_sec],
+ num_col, '-1 0', side,
+ add)
+ self.rows[i][ind2] = self._displ_add_del_sec(self[i][type_sec],
+ num_col, 'l', side,
+ add)
+ self._execute_update()
+
+ def _displ_check_type_col(self, name_sec, type_sec):
+ """Return
+ """
+ ind = self.cols_names.index(name_sec)
+ ind2 = self.cols_names.index(type_sec)
+ if self.rows[0][ind] != '':
+ if ';' in self.rows[0][ind]:
+ len_secc = len(self.rows[0][ind].split(';'))
+ else:
+ len_secc = 1
+ else:
+ return None
+
+ for i in range(len(self.rows)):
+ if self.rows[i][ind2] == '':
+ type_secc = ''
+ for _ in range(len_secc):
+ type_secc += 'l;'
+ self.rows[i][ind2] = type_secc[:-1]
+
+ def _displ_add_del_sec(self, sec, index, values, side, add):
+ """Return
+ """
+ if sec != '':
+ if ';' in sec:
+ sec_out = sec.split(';')
+ else:
+ sec_out = [sec]
+ if index > len(sec_out):
+ index = len(sec_out)
+ if side == 'left':
+ index = len(sec_out) - index
+ if add:
+ sec_out.insert(index, values)
+ return ';'.join(sec_out)
+ else:
+ if index > len(sec_out) - 1:
+ index = len(sec_out) - 1
+ del sec_out[index]
+ return ';'.join(sec_out)
+ else:
+ if add:
+ return values
+ else:
+ return ''
+
+ def _displ_init_vals(self):
+ """Return
+ """
+ values = INIT_VALUES[self.name]
+ if self[0]['sec_left'] != '':
+ num = '-1 0'
+ typ = 'l'
+ if ';' in self[0]['sec_left']:
+ for _ in range(len(self[0]['sec_left'].split(';')) - 1):
+ num += ';-1 0'
+ typ += ';l'
+ INIT_VALUES[self.name][1] = num
+ INIT_VALUES[self.name][3] = typ
+
+ if self[0]['sec_right'] != '':
+ num = '-1 0'
+ typ = 'l'
+ if ';' in self[0]['sec_right']:
+ for _ in range(len(self[0]['sec_right'].split(';')) - 1):
+ num += ';-1 0'
+ typ += ';l'
+ INIT_VALUES[self.name][2] = num
+ INIT_VALUES[self.name][4] = typ
+ return values
+
+ def add_row(self, list_pks, plant):
+ """Return
+ """
+ col_pks = self.get_column('pk')
+
+ list_pks2 = []
+ for npk in list_pks:
+ if float(npk) not in col_pks:
+ list_pks2.append(npk)
+
+ if list_pks2 == []:
+ return None
+
+ self.polygon.open('rw', self.layer, with_z=True,
+ tab_name=self.tab_name)
+ if self.name == '_Displ':
+ self._displ_init_vals()
+
+ for npk in list_pks2:
+ INIT_VALUES[self.name][0] = float(npk)
+ r_pnt = plant.get_roadpoint(float(npk))
+ cat = len(self.rows) + 1
+ self.rows.append([cat] + INIT_VALUES[self.name])
+
+ self.polygon.write(r_pnt, cat, INIT_VALUES[self.name])
+ self.polygon.table.conn.commit()
+ self.polygon.close()
+
+ self.update_table(plant)
+
+ # Rewrite other tables
+ def update_table(self, plant=None):
+ """Return
+ """
+ self.rows.sort(key=lambda x: float(x[1]))
+ self.rows[0][1] = 0
+ cats = [row[0] for row in self.rows]
+
+ if plant:
+ self.rows[-1][1] = plant.length()
+ for i, row in enumerate(self.rows):
+ r_pnt = plant.get_roadpoint(row[1])
+ if row[0] > i + 1 and i + 1 not in cats:
+ self.rewrite_new(r_pnt, row, i + 1)
+ del cats[cats.index(row[0])]
+ # elif row[0] == i + 1:
+ else:
+ row[0] = i + 1
+ self.rewrite_obj(r_pnt, row)
+ else:
+ self.rows[-1][1] = self.polyline.length()
+ self.rewrite_obj(self.polyline[0], self.rows[0])
+ self.rewrite_obj(self.polyline[-1], self.rows[-1])
+
+ def update_table_plan(self):
+ """Return None
+ Polygon to table plant
+ """
+ self._plan_set_dist_accum()
+ poly_dist = [self.polyline[i].distance(self.polyline[i + 1]) for i in
+ range(len(self.polyline) - 1)]
+
+ for i, row in enumerate(self.rows):
+
+ self.rewrite_obj(self.polyline[i], row)
+
+ if len(self.rows) < len(self.polyline):
+
+ self.polygon.open('rw', self.layer, with_z=True)
+
+ for i in range(len(self), len(self.polyline)):
+ self.rows.append(INIT_VALUES['_Plan'])
+ self.rows[i][0] = poly_dist[-1] + self.rows[i - 1][1]
+ self.polygon.write(self.polyline[i], i + 1, self.rows[i])
+
+ self.polygon.table.conn.commit()
+ self.polygon.close()
+
+ def _plan_set_dist_accum(self):
+ """Return
+ """
+ dist = 0
+ for i in range(0, len(self.rows) - 1):
+ self.rows[i][1] = dist
+ dist += self.polyline[i].distance(self.polyline[i + 1])
+ self.rows[-1][1] = dist
+
+
+# =============================================
+# PLANT
+# =============================================
+
+class RoadTables(object):
+ """ Return
+ """
+ def __init__(self, road_name, polygon=None):
+ """ Return
+ """
+ self.road_name = road_name
+ self.polygon = polygon
+
+ self.polygon.open('r')
+ self.polyline = self.polygon.cat(1, 'lines', 1)[0]
+ self.polygon.close()
+
+ self.tables = dict()
+
+ self.gen_tables()
+# self.update_tables()
+
+ def get_tables_names(self):
+ """Return
+ """
+ names = []
+ for tab_name in TABLES_NAMES:
+ exist = 0
+ if tab_name == 'first':
+ names.insert(0, [self.road_name, '', ''])
+ continue
+ for tab in [link.table_name for link in self.polygon.dblinks]:
+
+ if tab_name in tab:
+ names.append(tab.split(tab_name))
+ names[-1].insert(1, tab_name)
+ exist = 1
+ if not exist:
+ names.append([self.road_name, tab_name, ''])
+ return names
+
+ @time_func
+ def new_map(self, mapa, layer, tab_sufix, objs, values, tab_subname=''):
+ """Return
+ """
+ map_out = VectorTopo(mapa)
+ if objs == [] or objs is None:
+ return None
+
+ tab_sufix_out = OUT_TABLES_NAMES[tab_sufix]
+ tab_name = self.road_name + tab_sufix_out + tab_subname
+
+ columns = OUT_TABLES[tab_sufix]
+ if layer == 1:
+ map_out.open('w', layer=layer, with_z=True, tab_name=tab_name,
+ tab_cols=columns)
+ else:
+ map_out.open('rw')
+ link = Link(layer, tab_name, tab_name, 'cat' + str(layer))
+ map_out.dblinks.add(link)
+ table = link.table()
+ if not table.exist():
+ table.create(columns)
+ table.conn.commit()
+ map_out.close()
+
+ map_out.open('rw', layer=layer, with_z=True)
+ for i, obj in enumerate(objs):
+ map_out.write(obj, i + 1, values[i])
+ map_out.table.conn.commit()
+ map_out.close()
+
+ @time_func
+ def gen_tables(self):
+ """Return None
+ """
+ for i, name in enumerate(self.get_tables_names()):
+ namedic = name[1] + name[2]
+ if name[1] == '':
+ namedic = 'first'
+
+ self.tables[namedic] = \
+ RoadTable(self.polygon, self.polyline, i + 1, name[0] +
+ name[1] + name[2], name[1])
+
+ @time_func
+ def update_tables(self):
+ """Return None
+ """
+ for name, tab in self.tables.items():
+ if name == '_Plan':
+ tab.update_table_plan()
+ elif name != 'first':
+ tab.update_table()
+
+ @time_func
+ def update_tables_pnts(self, plant):
+ """Return None
+ """
+ for tab in self.tables.values():
+ if tab.name not in ['', '_Plan']:
+ tab.update_table(plant)
+
+ def add_table(self, tab_sufix, tab_subname):
+ """Return
+ """
+ if tab_sufix not in ['_Displ', '_Marks']:
+ grass.warning('Only Displ or Marks tables can be used')
+ return None
+ tab_name = self.road_name + tab_sufix + tab_subname
+ n_layer = self.polygon.dblinks.num_dblinks()
+ if tab_name in [link.table_name for link in self.polygon.dblinks]:
+ grass.warning('table exist')
+ else:
+ self.tables[tab_sufix + tab_subname] = \
+ RoadTable(self.polygon, self.polyline, n_layer + 1,
+ tab_name, tab_sufix)
+
+ def add_row(self, list_pks, plant, tab_sufix, tab_subname):
+ """Return
+ """
+ self.tables[tab_sufix + tab_subname].add_row(list_pks, plant)
+
+ def get_tables_pks(self):
+ """Return
+ """
+ list_pks = []
+ for tab in self.tables.values():
+ if tab.name in ['_Displ', '_Terr']:
+ pks = tab.get_column('pk')[1:-1]
+ for npk in pks:
+ if npk not in list_pks:
+ list_pks.append(npk)
+ return list_pks
+
+ def create_backup(self, filename):
+ """Return
+ """
+ sal = 'echo "'
+ sal += 'L ' + str(len(self.polyline)) + ' 1\n'
+ for pnt in self.polyline:
+ sal += ' ' + str(pnt.x) + ' ' + str(pnt.y) + '\n'
+ sal += ' 1 1\n'
+
+ self.polygon.open('r')
+ for table in self.tables.values():
+ if table.name != '':
+ for row in table.rows:
+ sal += 'P 1 1\n'
+ pnt = self.polygon.cat(row[0], 'points', table.layer)[0]
+ sal += ' ' + str(pnt.x) + ' ' + str(pnt.y) + '\n'
+ sal += ' ' + str(table.layer) + ' ' + str(row[0]) + '\n'
+ self.polygon.close()
+
+ sal += '" | v.in.ascii -n input=- output=' + self.road_name
+ sal += ' format=standard --o \n\n'
+
+ for table in self.tables.values():
+ tab_name = table.name
+ cat = str(table.layer)
+ if tab_name == '':
+ tab_name = 'first'
+ cat = ''
+
+ cols = []
+ for key1, val1 in TABLES[tab_name][1:]:
+ if 'INTEGER' in val1:
+ val1 = 'INT'
+ if 'TEXT' in val1:
+ val1 = 'VARCHAR(25)'
+ cols.append((key1, val1))
+
+ sal += 'v.db.addtable map=' + self.road_name + \
+ ' table=' + self.road_name + table.name + \
+ ' layer=' + str(table.layer) + \
+ ' key=cat' + cat + \
+ ' columns="' + ','.join(["%s %s" % (key, str(val).lower())
+ for key, val in cols]) + '"\n'
+
+ sal += '\n' + 'echo "'
+ for table in self.tables.values():
+ for row in table.rows:
+ vals = ','.join(["%s='%s'" % (key, val) for key, val in
+ zip(table.cols_names[1:], row[1:])])
+ cond = "%s=%s" % (table.cols_names[0], row[0])
+ sal += 'UPDATE ' + self.road_name + table.name + \
+ ' SET ' + vals + ' WHERE ' + cond + ';\n'
+ sal += '" | db.execute input=- \n'
+
+ with open(filename, 'w') as file:
+ file.write(sal)
+
+if __name__ == '__main__':
+ import doctest
+ doctest.testmod()
Property changes on: grass-addons/grass7/vector/v.civil/road_tables.py
___________________________________________________________________
Added: svn:mime-type
+ text/x-python
Added: svn:eol-style
+ native
Added: grass-addons/grass7/vector/v.civil/road_terr.py
===================================================================
--- grass-addons/grass7/vector/v.civil/road_terr.py (rev 0)
+++ grass-addons/grass7/vector/v.civil/road_terr.py 2016-07-01 22:30:22 UTC (rev 68831)
@@ -0,0 +1,382 @@
+# -*- coding: utf-8 -*-
+"""
+Created on Thu Sep 11 00:29:15 2014
+
+ at author: meskal
+"""
+
+import math
+# import time
+
+import road_base as Base
+from grass.pygrass.raster import RasterRow
+
+from grass.pygrass.vector.geometry import Point
+from grass.pygrass.gis.region import Region
+from grass.pygrass.vector.geometry import Line
+from grass.pygrass.vector.geometry import Boundary
+from grass.pygrass.vector.geometry import Area
+
+def get_rgb(type_terr):
+ """ Return
+ """
+ if type_terr == 'Cut':
+ return '165:50:0'
+ else:
+ return '255:165:0'
+
+
+def get_side(left):
+ """ Return
+ """
+ if left:
+ return 'left'
+ else:
+ return 'right'
+
+
+# =============================================
+# PLANT
+# =============================================
+
+class Talud(object):
+ """ Return
+ """
+ def __init__(self, pks, cut, fill, left=True, terr=None):
+ """ Return
+ """
+ self.pks = pks
+ self.cut = [float(p) for p in cut]
+ self.fill = [float(p) for p in fill]
+ self.terr = terr
+
+ self.left = left
+
+ if self.left:
+ self.g90 = -math.pi / 2
+ else:
+ self.g90 = math.pi / 2
+
+ self.roadlines = []
+ self.roadline = None
+
+ def _get_cutfill_slope(self, r_pnt_d):
+ """Return
+ """
+ for i in range(len(self.pks) - 1):
+ if self.pks[i] <= r_pnt_d.npk < self.pks[i + 1]:
+
+ if r_pnt_d.z < r_pnt_d.terr:
+ slope = self.cut
+ else:
+ slope = self.fill
+
+ if slope[i] is not None or slope[i + 1] is not None:
+
+ return slope[i] + ((r_pnt_d.npk - self.pks[i]) *
+ (slope[i + 1] - slope[i])) / \
+ (self.pks[i + 1] - self.pks[i])
+
+ def _funct(self, r_pnt_d, len_i, sig, azim, slope):
+ """ Return
+ """
+ x_1 = r_pnt_d.x + len_i * math.sin(azim)
+ y_1 = r_pnt_d.y + len_i * math.cos(azim)
+ z_t = self.terr.get_value(Base.Point(x_1, y_1))
+ z_1 = r_pnt_d.z + sig * len_i * slope
+ return dict(zip(['z_1', 'z_t', 'x_1', 'y_1'], [z_1, z_t, x_1, y_1]))
+
+ def get_pnt_slope(self, r_pnt, r_pnt_d):
+ """ Return
+ """
+ azim = r_pnt_d.azi + self.g90
+
+ if r_pnt_d.z > r_pnt_d.terr: # Terraplen
+ sig = -1
+ type_t = 'Fill'
+ else:
+ sig = 1
+ type_t = 'Cut'
+
+ z_t = r_pnt_d.terr
+ z_1 = r_pnt_d.z
+
+ slop = self._get_cutfill_slope(r_pnt_d)
+ if slop is None:
+ return None
+
+ len_i = 0
+ while -sig * z_1 > -sig * z_t or len_i > 1000:
+ len_i += 1
+
+ x_1 = r_pnt_d.x + len_i * math.sin(azim)
+ y_1 = r_pnt_d.y + len_i * math.cos(azim)
+ z_t = self.terr.get_value(Base.Point(x_1, y_1))
+ z_1 = r_pnt_d.z + sig * len_i * slop
+
+ len_a = len_i - 1
+ len_b = len_i
+ len_c = (len_a + len_b) / 2.0
+
+ while (len_b - len_a) / 2.0 > 0.001:
+ eq_c = self._funct(r_pnt_d, len_c, sig, azim, slop)
+ eq_a = self._funct(r_pnt_d, len_a, sig, azim, slop)
+ if eq_c['z_1'] == eq_c['z_t']:
+ break
+ elif (eq_a['z_1'] - eq_a['z_t']) * (eq_c['z_1'] - eq_c['z_t']) < 0:
+ len_b = len_c
+ else:
+ len_a = len_c
+ len_c = (len_a + len_b) / 2.0
+
+ eq_c = self._funct(r_pnt_d, len_c, sig, azim, slop)
+ pnt = Base.RoadPoint(Point(eq_c['x_1'], eq_c['y_1'], eq_c['z_1']),
+ r_pnt.npk, r_pnt_d.azi, '')
+ pnt.terr_type = type_t
+ pnt.dist_displ = pnt.distance(r_pnt)
+ return pnt
+
+ def get_pnts_slope(self, list_r_pnts, list_pnts_d):
+ """Return
+ """
+ list_pnts_t = []
+ for i, r_pnt_d in enumerate(list_pnts_d):
+ if r_pnt_d is not None:
+ pnt_t = self.get_pnt_slope(list_r_pnts[i], r_pnt_d)
+ list_pnts_t.append(pnt_t)
+ else:
+ list_pnts_t.append(None)
+ return list_pnts_t
+
+ def split_slope_line(self, rline):
+ """Return
+ """
+ list_pnts_t = [[]]
+ for line in rline:
+ if line is not None:
+ pnt_ant = line
+ break
+ for pnt_t in rline:
+ if pnt_t is not None:
+ if pnt_ant.terr_type != pnt_t.terr_type:
+ list_pnts_t.append([])
+ list_pnts_t[-1].append(pnt_t)
+ pnt_ant = pnt_t
+ elif list_pnts_t[-1] != []:
+ list_pnts_t.append([])
+ if list_pnts_t[-1] == []:
+ del list_pnts_t[-1]
+ return list_pnts_t
+
+ def set_roadlines(self, roadline, roadline_d):
+ """ Return
+ """
+ self.terr.set_pnts_terr(roadline_d)
+
+ line1 = self.get_pnts_slope(roadline, roadline_d)
+ name = 'Slope_' + get_side(self.left)
+ attrs = [name, 1, get_side(self.left), 1, '0:0:0']
+ self.roadline = Base.RoadLine(line1, attrs, name)
+ lines = self.split_slope_line(line1)
+ for i, line in enumerate(lines):
+ if line != []:
+ # Name lenght type param rgb
+ name = 'Slope_' + get_side(self.left) + '_' + str(i + 1)
+ attrs = [name, -1, line[-1].terr_type, i + 1,
+ get_rgb(line[-1].terr_type)]
+ self.roadlines.append(Base.RoadLine(line, attrs, name))
+
+
+# =============================================
+# Taludes
+# =============================================
+
+class Taludes(object):
+ """ Return
+ """
+ def __init__(self, polygon=None, tabla=None, terr=None):
+ """ Return
+ """
+ self.polygon = polygon
+ self.tabla = tabla
+ self.terr = terr
+
+ self.pks = []
+ self.cut = {'left': [], 'right': []}
+ self.fill = {'left': [], 'right': []}
+
+ self._init_talud()
+
+ self.talud_left = Talud(self.pks, self.cut['left'], self.fill['left'],
+ left=True, terr=self.terr)
+ self.talud_right = Talud(self.pks, self.cut['right'],
+ self.fill['right'], left=False,
+ terr=self.terr)
+
+ def __repr__(self):
+ """ Return
+ """
+ return 'Taludes '
+
+ def _init_talud(self):
+ """ Return
+ """
+ for dat in self.tabla:
+
+ self.pks.append(dat['pk'])
+ self.cut['left'].append(dat['cut_left'])
+ self.cut['right'].append(dat['cut_right'])
+ self.fill['left'].append(dat['fill_left'])
+ self.fill['right'].append(dat['fill_right'])
+
+ def get_pnts(self, r_pnt, r_pnts_d):
+ """ Return
+ """
+ pto1 = None
+ pto2 = None
+ if r_pnts_d[0][-1] is not None:
+ pto1 = self.talud_left.get_pnt_slope(r_pnt, r_pnts_d[0][-1])
+ if r_pnts_d[1][-1] is not None:
+ pto2 = self.talud_right.get_pnt_slope(r_pnt, r_pnts_d[1][-1])
+ return [pto1, pto2]
+
+ def get_lines(self):
+ """ Return
+ """
+ list_lines = []
+ list_attrs = []
+ for r_line in self.talud_left.roadlines:
+ objs, values = r_line.get_line_attrs(set_leng=1)
+ list_lines.extend(objs)
+ list_attrs.extend(values)
+
+ for r_line in self.talud_right.roadlines:
+ objs, values = r_line.get_line_attrs(set_leng=1)
+ list_lines.extend(objs)
+ list_attrs.extend(values)
+
+ return list_lines, list_attrs
+
+ def set_roadlines(self, roadline, displ):
+ """ Return
+ """
+ if displ.displines == []:
+ return None, None
+
+ self.talud_left.set_roadlines(roadline,
+ displ.displines_left[-1].roadline)
+ self.talud_right.set_roadlines(roadline,
+ displ.displines_right[-1].roadline)
+
+ def get_areas(self, displ):
+ """ Return
+ """
+ areas = []
+ list_attrs = []
+
+ for r_line in self.talud_left.roadlines:
+ line2 = [displ.displines_left[-1].roadline.get_by_pk(r_pnt.npk)
+ for r_pnt in r_line if r_pnt is not None]
+ lines = r_line.get_area(line2)
+
+ for j in range(len(lines)):
+ list_attrs.extend([r_line.attrs])
+ areas.extend(lines)
+
+ for r_line in self.talud_right.roadlines:
+ line2 = [displ.displines_right[-1].roadline.get_by_pk(r_pnt.npk)
+ for r_pnt in r_line if r_pnt is not None]
+ lines = r_line.get_area(line2)
+
+ for j in range(len(lines)):
+ list_attrs.extend([r_line.attrs])
+ areas.extend(lines)
+
+ return areas, list_attrs
+
+ def get_hull(self, displ):
+ """ Return
+ """
+ line1 = []
+ for i, pnt_t in enumerate(self.talud_left.roadline):
+ if pnt_t is not None:
+ line1.append(pnt_t)
+ else:
+ for dline in displ.displines_left[::-1]:
+ if dline.roadline[i] is not None:
+ line1.append(dline.roadline[i])
+ break
+ line2 = []
+ for i, pnt_t in enumerate(self.talud_right.roadline):
+ if pnt_t is not None:
+ line2.append(pnt_t)
+ else:
+ for dline in displ.displines_right[::-1]:
+ if dline.roadline[i] is not None:
+ line2.append(dline.roadline[i])
+ break
+ line2 = line2[::-1]
+ line2.append(line1[0])
+ line1.extend(line2)
+ for i, pto in enumerate(line1):
+ line1[i].z = 0
+ line = Boundary(points=line1)
+ attrs = [['Hull', line.length()]]
+ return [line], attrs
+
+
+# =============================================
+# Terrain
+# =============================================
+
+class Terrain(object):
+ """ Return
+ """
+ def __init__(self, mapname=None):
+ """ Return
+ """
+ self.mapname = mapname
+
+ self.elev = []
+ self._init_elev()
+
+ region = Region()
+ self.xref = region.west
+ self.yref = region.north
+ self.xres = region.ewres
+ self.yres = region.nsres
+
+ def _init_elev(self):
+ """ Return
+ """
+ with RasterRow(self.mapname) as rrow:
+ for row in rrow:
+ self.elev.append([])
+ for elem in row:
+ self.elev[-1].append(elem)
+
+ def get_value(self, point):
+ """ Return
+ """
+ pto_col = int((point.x - self.xref) / self.xres)
+ pto_row = int((self.yref - point.y) / self.yres)
+
+ return self.elev[pto_row][pto_col]
+
+ def set_pnts_terr(self, list_r_pnts):
+ """Return
+ """
+ for r_pnt in list_r_pnts:
+ if r_pnt is not None:
+ self.set_pnt_terr(r_pnt)
+ else:
+ return None
+
+ def set_pnt_terr(self, r_pnt):
+ """ Return
+ """
+ r_pnt.terr = self.get_value(r_pnt)
+
+if __name__ == '__main__':
+ import doctest
+ doctest.testmod()
Property changes on: grass-addons/grass7/vector/v.civil/road_terr.py
___________________________________________________________________
Added: svn:mime-type
+ text/x-python
Added: svn:eol-style
+ native
Added: grass-addons/grass7/vector/v.civil/road_topotools.py
===================================================================
--- grass-addons/grass7/vector/v.civil/road_topotools.py (rev 0)
+++ grass-addons/grass7/vector/v.civil/road_topotools.py 2016-07-01 22:30:22 UTC (rev 68831)
@@ -0,0 +1,434 @@
+#!/usr/bin/python
+
+"""
+Sample Python script to access vector data using GRASS Ctypes
+interface
+"""
+
+# import os, sys
+
+import grass.lib.gis as GrassGis
+import grass.lib.vector as GrassVect
+import time
+import os
+import sys
+import math
+import grass.script as grass
+# from grass.pygrass.gis.region import Region
+
+from grass.pygrass.vector import VectorTopo
+from grass.pygrass.vector.geometry import Point
+from grass.pygrass.vector.geometry import Line
+# from grass.pygrass.vector.geometry import Boundary
+# from grass.pygrass.vector.geometry import GEOOBJ as _GEOOBJ
+
+import road_base as Base
+
+
+def time_func(funcion_f):
+ """Return
+ """
+ def funcion_r(*arg):
+ """Return
+ """
+ t_1 = time.clock()
+ res = funcion_f(*arg)
+ t_2 = time.clock()
+ print('%s tarda %0.5f ms' % (funcion_f.__name__, (t_2 - t_1) * 1000.0))
+ return res
+ return funcion_r
+
+
+#########################################################
+class Topo(object):
+ """ Return
+ """
+ def __init__(self, name_map=''):
+ """ Return
+ """
+ self.name_map = name_map
+
+ def uppoints(self):
+ """ Return
+ """
+ name_map = self.name_map + '__Topo'
+ topo = VectorTopo(name_map)
+ topo.open('r', layer=1)
+
+ pts_org = []
+ pts_chg = []
+ attrs = []
+ for i in range(1, len(topo) + 1):
+ act = topo.read(i).attrs['action']
+ if act != '':
+ cat = topo.read(i).attrs['cat']
+ pto_org = topo.cat(cat, 'points', 1)[0]
+ pto_chg = Point(pto_org.x, pto_org.y, pto_org.z)
+ if topo.read(i).attrs['x'] is not None:
+ pto_chg.x = float(topo.read(i).attrs['x'])
+ if topo.read(i).attrs['y'] is not None:
+ pto_chg.y = float(topo.read(i).attrs['y'])
+ if topo.read(i).attrs['z'] is not None:
+ pto_chg.z = float(topo.read(i).attrs['z'])
+
+ pts_org.append(pto_org)
+ pts_chg.append(pto_chg)
+ attrs.append([cat, topo.read(i).attrs['pk'],
+ topo.read(i).attrs['name'],
+ topo.read(i).attrs['azi'],
+ topo.read(i).attrs['p_type'],
+ topo.read(i).attrs['align'],
+ topo.read(i).attrs['vparam'],
+ topo.read(i).attrs['v_type'],
+ topo.read(i).attrs['terr'],
+ topo.read(i).attrs['t_type'],
+ topo.read(i).attrs['dist_d'],
+ pto_chg.x, pto_chg.y, pto_chg.z, ''])
+ topo.close()
+ if pts_org != []:
+ topo.open('rw', 1, with_z=True)
+ for i, pto in enumerate(pts_org):
+ topo.rewrite(pto, pts_chg[i], attrs[i][1:])
+ topo.table.conn.commit()
+ topo.close()
+
+ def pts_info(self, npk, road):
+ """ Return
+ """
+ r_pnt = road.plant.get_roadpoint(float(npk))
+ road.vert.set_elev(r_pnt)
+ road.terr.set_pnt_terr(r_pnt)
+ print('Axis point')
+ print(r_pnt.get_info())
+ r_pnts_d = road.displ.find_cutoff(r_pnt)
+
+ for side in r_pnts_d:
+ for pnt in side:
+ if pnt is not None:
+ road.terr.set_pnt_terr(pnt)
+
+ r_pnts_t = road.taludes.get_pnts(r_pnt, r_pnts_d) or []
+ print('Slope points')
+ for pnt in r_pnts_t:
+ if pnt is not None:
+ print(pnt.get_info())
+ print('Displaced points')
+ for side in r_pnts_d:
+ for pnt in side:
+ if pnt is not None:
+ print(pnt.get_info())
+
+ def roundabout(self, radio, radio2, azimut, center):
+ """ Return
+ """
+ center = [float(p) for p in center.split(',')]
+ pto_c = Base.RoadPoint(Point(center[0], center[1], 0))
+ radio = float(radio)
+ radio2 = float(radio2)
+ azi = float(azimut)
+
+ pto_1 = pto_c.project(radio2, azi)
+ pto_2 = pto_1.project(radio, azi + math.pi / 2)
+ pto_3 = pto_2.project(radio2, azi + math.pi)
+ pto_4 = pto_3.project(radio, azi + 3 * math.pi / 2)
+ pto_5 = pto_4.project(radio2, azi)
+ pto_6 = pto_5.project(radio, azi + math.pi / 2)
+
+ sal = ''
+ sal += "L 6 1\n"
+ for pto in [pto_1, pto_2, pto_3, pto_4, pto_5, pto_6]:
+ sal += ' ' + str(pto.x) + ' ' + str(pto.y) + ' ' + \
+ str(pto.z) + '\n'
+ sal += "1 1\n"
+
+ grass.write_command('v.in.ascii', flags='nz',
+ output=self.name_map, stdin=sal,
+ input='-', format='standard', quiet=True)
+ grass.run_command('v.road', flags='r', name=self.name_map)
+
+ sal = ""
+ for i in range(1, 5):
+ sal += "UPDATE " + self.name_map + "_Plan SET "
+ sal += "radio=" + str(radio)
+ sal += " WHERE cat2=" + str(i + 1) + " ;\n"
+ grass.write_command('db.execute', stdin=sal, input='-', quiet=True)
+
+
+#########################################################
+class Triang(object):
+ """ Return
+ """
+ def __init__(self, name_map):
+ """ Return
+ """
+ self.name_map = name_map + '__Topo'
+ self.ptosmap = self.name_map + '_pts'
+ self.breakmap = self.name_map + '_blines'
+ self.contornomap = self.name_map + '_Hull'
+
+ self.nametin = self.name_map + '_Tin'
+ self.namelines = self.name_map + '_lines'
+ self.namecurved = self.name_map + '_Curves'
+
+ def split_maps(self):
+ """ Return
+ """
+ grass.message("Spliting in points and breaklines maps")
+
+ topo = VectorTopo(self.name_map)
+ topo.open('r')
+
+ points = []
+ lines = []
+ for algo in range(1, topo.number_of("points") + 1):
+ if isinstance(topo.read(algo), Point):
+ points.append(topo.read(algo))
+ if isinstance(topo.read(algo), Line):
+ lines.append(topo.read(algo))
+ topo.close()
+
+ new1 = VectorTopo(self.ptosmap)
+ new1.open('w', with_z=True)
+ for pnt in points:
+ new1.write(pnt)
+ new1.close()
+
+ new1 = VectorTopo(self.breakmap)
+ new1.open('w', layer=1, with_z=True)
+ for line in lines:
+ new1.write(line)
+ new1.close()
+
+ def get_area_hull(self):
+ """ Return
+ """
+ grass.run_command('v.centroids', input=self.contornomap,
+ output=self.contornomap + '_area',
+ overwrite=True, quiet=True)
+
+ def cut_by_hull(self):
+ """ Return
+ """
+ grass.run_command('v.category', input=self.namecurved,
+ output=self.namecurved + '_cat', option='add',
+ overwrite=True, quiet=True)
+
+ grass.run_command('v.db.addtable', map=self.namecurved + '_cat',
+ columns="x double,y double,z double", quiet=True)
+
+ grass.run_command('v.to.db', map=self.namecurved + '_cat',
+ option='start', columns='x,y,z', units='meters',
+ overwrite=True, quiet=True)
+
+ grass.run_command('v.overlay', ainput=self.namecurved + '_cat',
+ atype='line', binput=self.contornomap + '_area',
+ operator='and', output=self.namecurved,
+ overwrite=True, quiet=True)
+
+# def tin_to_raster(self):
+# """ Return
+# """
+# grass.run_command('v.tin.to.raster', map=self.nametin,
+# output=self.name_map+"_TinDem_borrar",
+# overwrite=True, quiet=True)
+#
+# grass.run_command('v.to.rast', input=self.contornomap + '_area',
+# output=self.contornomap + '_area', use='val',
+# overwrite=True, quiet=True)
+#
+# os.system("r.mapcalc '" + self.name_map + "_TinDem" +
+# " = if(" + self.contornomap + '_area' + "==1" + ", " +
+# self.name_map + "_TinDem_borrar" + ", null())' --o --q")
+#
+# grass.run_command('r.contour', input=self.name_map + "_TinDem",
+# output=self.name_map + "_TinDemCurvas",
+# step=1, overwrite=True, quiet=True)
+#
+# grass.run_command('g.remove', flags='f', type='raster',
+# name=self.name_map + "_TinDem_borrar")
+#
+# def nnbathy(self):
+# """ Return
+# """
+# grass.run_command('v.to.rast', input=self.name_map,
+# output=self.name_map, use='z',
+# overwrite=True, quiet=True)
+#
+# os.system('/mnt/trb/addons/r.surf.nnbathy/r.surf.nnbathy.sh input=' +
+# self.name_map + ' output=' + self.name_map +
+# "_NNbathyDem_borrar" + ' alg=l --o --q')
+#
+# grass.run_command('v.to.rast', input=self.contornomap + '_area',
+# output=self.contornomap + '_area', use='val',
+# overwrite=True, quiet=True)
+#
+# os.system("r.mapcalc '" + self.name_map + "_NNbathyDem" +
+# " = if(" + self.contornomap + '_area' + "==1" + ", " +
+# self.name_map + "_NNbathyDem_borrar" + ", null())' --o --q")
+#
+# grass.run_command('r.contour', input=self.name_map + "_NNbathyDem",
+# output=self.name_map + "_NNbathyDemCurvas",
+# step=1, overwrite=True, quiet=True)
+#
+# grass.run_command('g.remove', flags='f', type='raster',
+# name=self.name_map+"_NNbathyDem_borrar")
+
+ def triangle(self):
+ """ Return
+ """
+ grass.message("Triangulating tin")
+ cmd = '/mnt/trb/addons/v.triangle/v.triangle.v7 points=' + self.ptosmap
+ if self.breakmap != "":
+ cmd += ' lines=' + self.breakmap
+ cmd += ' tin=' + self.nametin + ' --o --q'
+ os.system(cmd)
+
+ def delaunay(self):
+ """ Return
+ """
+ grass.run_command('v.delaunay', input=self.name_map,
+ output=self.nametin,
+ overwrite=True, quiet=True)
+
+ def curved(self):
+ """ Return
+ """
+ mapset = GrassGis.G_find_vector2(self.nametin, "")
+ if not mapset:
+ sys.exit("Vector map <%s> not found" % self.nametin)
+
+ # define map structure
+ map_info = GrassGis.pointer(GrassVect.Map_info())
+
+ # define open level (level 2: topology)
+ GrassVect.Vect_set_open_level(2)
+
+ # open existing vector map
+ GrassVect.Vect_open_old(map_info, self.nametin, mapset)
+
+ print('Calculating curves')
+
+ allrectas = []
+ rectas = self.get_rectas(map_info)
+
+ for nivel in rectas:
+ for recta in nivel:
+ allrectas.append(recta)
+
+ GrassVect.Vect_close(map_info)
+
+ new = VectorTopo(self.namelines)
+ new.open('w', with_z=True)
+
+ for line in allrectas:
+ new.write(Line(line))
+ new.close()
+
+ grass.run_command('v.build.polylines', input=self.namelines,
+ output=self.namecurved,
+ overwrite=True, quiet=True)
+
+ @time_func
+ def get_tin_maxmin(self, map_info):
+ """ Return
+ """
+ line1 = Line()
+ num_areas = GrassVect.Vect_get_num_areas(map_info)
+ max_z = 0
+ min_z = 100000
+ for area_id in range(1, num_areas + 1):
+
+ GrassVect.Vect_get_area_points(map_info, area_id, line1.c_points)
+
+ pto1_z = line1.c_points.contents.z[0]
+ pto2_z = line1.c_points.contents.z[1]
+ pto3_z = line1.c_points.contents.z[2]
+
+ min_ptos = min(pto1_z, pto2_z, pto3_z)
+ max_ptos = max(pto1_z, pto2_z, pto3_z)
+ if min_ptos < min_z:
+ min_z = min_ptos
+ if max_ptos > max_z:
+ max_z = max_ptos
+ return [int(math.floor(min_z)), int(math.ceil(max_z))]
+
+ @time_func
+ def get_rectas(self, map_info):
+ """ Return
+ """
+ line1 = Line()
+
+ max_min = self.get_tin_maxmin(map_info)
+ rectas = [[] for p in range(max_min[0], max_min[1] + 1)]
+ ptos = [[] for p in range(max_min[0], max_min[1] + 1)]
+
+ num_areas = GrassVect.Vect_get_num_areas(map_info)
+ for area_id in range(1, num_areas + 1):
+
+ GrassVect.Vect_get_area_points(map_info, area_id, line1.c_points)
+
+ pto1_x = line1.c_points.contents.x[0]
+ pto1_y = line1.c_points.contents.y[0]
+ pto1_z = line1.c_points.contents.z[0]
+ pto2_x = line1.c_points.contents.x[1]
+ pto2_y = line1.c_points.contents.y[1]
+ pto2_z = line1.c_points.contents.z[1]
+ pto3_x = line1.c_points.contents.x[2]
+ pto3_y = line1.c_points.contents.y[2]
+ pto3_z = line1.c_points.contents.z[2]
+
+ for i, z_z in enumerate(range(max_min[0], max_min[1] + 1)):
+
+ if pto1_z < z_z and pto2_z < z_z and pto3_z < z_z:
+ continue
+ if pto1_z > z_z and pto2_z > z_z and pto3_z > z_z:
+ continue
+ if pto1_z == z_z and pto2_z == z_z and pto3_z == z_z:
+ continue
+
+ pts = [[pto1_x, pto1_y, pto1_z],
+ [pto2_x, pto2_y, pto2_z],
+ [pto3_x, pto3_y, pto3_z]]
+ inf = [pto for pto in pts if pto[2] < z_z]
+ equal = [pto for pto in pts if pto[2] == z_z]
+ sup = [pto for pto in pts if pto[2] > z_z]
+
+ if ((len(inf) == 0 and len(sup) == 2) or
+ (len(inf) == 2 and len(sup) == 0)):
+ continue
+
+ if len(equal) == 2:
+ if equal[0] != equal[1]:
+ if equal not in ptos[i] and equal[::-1] not in ptos[i]:
+ rectas[i].append(equal)
+ ptos[i].append(equal)
+ continue
+
+ if len(inf) <= len(sup):
+ inf.extend(equal)
+ else:
+ sup.extend(equal)
+
+ if len(inf) < len(sup):
+ pto_a = inf[0]
+ pto_b = sup[0]
+ pto_c = sup[1]
+ else:
+ pto_a = sup[0]
+ pto_b = inf[0]
+ pto_c = inf[1]
+
+ t_1 = (z_z - pto_a[2]) / (pto_b[2] - pto_a[2])
+ xx1 = pto_a[0] + t_1 * (pto_b[0] - pto_a[0])
+ yy1 = pto_a[1] + t_1 * (pto_b[1] - pto_a[1])
+ pto_1 = Point(xx1, yy1, z_z)
+
+ t_2 = (z_z - pto_a[2]) / (pto_c[2] - pto_a[2])
+ xx2 = pto_a[0] + t_2 * (pto_c[0] - pto_a[0])
+ yy2 = pto_a[1] + t_2 * (pto_c[1] - pto_a[1])
+ pto_2 = Point(xx2, yy2, z_z)
+
+ rectas[i].append([pto_1, pto_2])
+
+ return rectas
+####################################################
Added: grass-addons/grass7/vector/v.civil/road_trans.py
===================================================================
--- grass-addons/grass7/vector/v.civil/road_trans.py (rev 0)
+++ grass-addons/grass7/vector/v.civil/road_trans.py 2016-07-01 22:30:22 UTC (rev 68831)
@@ -0,0 +1,361 @@
+# -*- coding: utf-8 -*-
+"""
+Created on Sat Aug 2 14:20:17 2014
+
+ at author: meskal
+"""
+
+#
+# import pygrass modules
+#
+import math
+
+# from grass.pygrass.vector import VectorTopo
+import road_base as Base
+
+# from grass.pygrass.vector.geometry import Point
+from grass.pygrass.vector.geometry import Line
+# from grass.pygrass.vector.geometry import Point
+
+
+class TransLine(object):
+ """ Return
+ """
+ def __init__(self, r_pnt=None, dist_left=None, dist_right=None):
+ """ Return
+ """
+ self.r_pnt = r_pnt
+ self.dist_left = dist_left
+ self.dist_right = dist_right
+
+ self.displ_left = []
+ self.displ_right = []
+
+ self.talud_left = None
+ self.talud_right = None
+
+ self.terr_pnts = None
+
+ def __str__(self):
+ """ Return
+ """
+ return "TransLine(" + str(self.r_pnt.npk) + ")"
+
+ def __repr__(self):
+ """ Return
+ """
+ return "TransLine(" + str(self.r_pnt.npk) + ")"
+
+ def length(self):
+ """ Return
+ """
+ return self.dist_left + self.dist_right
+
+ def _get_straight(self):
+ """ Return
+ """
+ p_left = self.r_pnt.parallel(self.dist_left, -math.pi / 2)
+ p_right = self.r_pnt.parallel(self.dist_right, math.pi / 2)
+ return Base.Straight(p_left, p_right)
+
+ def get_line(self):
+ """ Return
+ """
+ p_left = self.r_pnt.parallel(self.dist_left, -math.pi / 2)
+ p_right = self.r_pnt.parallel(self.dist_right, math.pi / 2)
+ return Line([p_left, p_right])
+
+ def set_displ(self, displaced):
+ """ Return
+ """
+ self.displ_left, self.displ_right = displaced.find_cutoff(self.r_pnt)
+
+ def set_talud(self, taludes, terr):
+ """ Return
+ """
+ if self.displ_left != [] and self.displ_left[-1] is not None:
+
+ terr.set_pnt_terr(self.displ_left[-1])
+ self.talud_left = \
+ taludes.talud_left.get_pnt_slope(self.r_pnt,
+ self.displ_left[-1])
+# if self.talud_left is None:
+# self.talud_left = Base.RoadPoint(Point(0,0,0))
+# self.talud_left.dist_displ = 0
+# self.talud_left.npk = -1
+
+ if self.displ_right != [] and self.displ_right[-1] is not None:
+ terr.set_pnt_terr(self.displ_right[-1])
+ self.talud_right = \
+ taludes.talud_right.get_pnt_slope(self.r_pnt,
+ self.displ_right[-1])
+# if self.talud_right is not None:
+# self.talud_right = Base.RoadPoint(Point(0,0,0))
+# self.talud_right.dist_displ = 0
+# self.talud_right.npk = -1
+
+ def set_terr_pnts(self, terr):
+ """ Return
+ """
+ max_left_width = self.max_left_width()
+ straight_1 = self._get_straight()
+ self.terr_pnts = straight_1.get_roadpnts(0, -1, 1)
+ terr.set_pnts_terr(self.terr_pnts)
+
+ if self.dist_left < max_left_width:
+ rest = max_left_width - self.dist_left
+ for i, r_pnt in enumerate(self.terr_pnts):
+ self.terr_pnts[i].npk = rest + r_pnt.npk
+
+ def get_ras_pnts(self):
+ """ Return
+ """
+ max_left_width = self.max_left_width()
+ line = []
+ if self.talud_left is not None:
+
+ self.talud_left.npk = max_left_width - self.talud_left.dist_displ
+ line.append(self.talud_left)
+
+ for r_pnt in self.displ_left[::-1]:
+ if r_pnt is not None:
+ r_pnt.npk = max_left_width - r_pnt.dist_displ
+ line.append(r_pnt)
+
+ r_pnt_c = Base.RoadPoint(self.r_pnt, max_left_width, self.r_pnt.azi)
+ line.append(r_pnt_c)
+
+
+ for r_pnt in self.displ_right:
+ if r_pnt is not None:
+ r_pnt.npk = max_left_width + r_pnt.dist_displ
+ line.append(r_pnt)
+
+ if self.talud_right is not None:
+ self.talud_right.npk = max_left_width + self.talud_right.dist_displ
+ line.append(self.talud_right)
+
+ return line
+
+ def max_left_width(self):
+ """ Return
+ """
+ if self.talud_left is not None:
+ return max(self.dist_left, self.talud_left.dist_displ)
+ return self.dist_left
+
+ def max_right_width(self):
+ """ Return
+ """
+
+ if self.talud_right is not None:
+ return max(self.dist_right, self.talud_right.dist_displ)
+ return self.dist_right
+
+ def _width_terr(self):
+ """ Return
+ """
+ return self.talud_left.dist_displ + self.talud_right.dist_displ
+
+ def _max_terr(self):
+ """ Return
+ """
+ return max([r_pnt.terr for r_pnt in self.terr_pnts])
+
+ def _min_terr(self):
+ """ Return
+ """
+ return min([r_pnt.terr for r_pnt in self.terr_pnts])
+
+ def _max_height_displ(self):
+ """ Return
+ """
+ lista = self.displ_left + self.displ_right
+ if self.talud_left is not None:
+ lista += [self.talud_left]
+ if self.talud_right is not None:
+ lista += [self.talud_right]
+ return max([r_pnt.z for r_pnt in lista if r_pnt is not None])
+
+ def _min_height_displ(self):
+ """ Return
+ """
+ lista = self.displ_left + self.displ_right
+ if self.talud_left is not None:
+ lista += [self.talud_left]
+ if self.talud_right is not None:
+ lista += [self.talud_right]
+ return min([r_pnt.z for r_pnt in lista if r_pnt is not None])
+
+ def max_height(self):
+ """ Return
+ """
+ return math.ceil(max(self._max_terr(), self._max_height_displ()))
+
+ def min_height(self):
+ """ Return
+ """
+ return math.floor(min(self._min_terr(), self._min_height_displ()))
+
+ def max_width(self):
+ """ Return
+ """
+ return max(self._width_terr(), self.length())
+
+
+class Trans(object):
+ """ Return
+ """
+ def __init__(self, polygon, tabla_iter, plant, vert, terr):
+ """ Return
+ """
+ self.polygon = polygon
+ self.tabla_iter = tabla_iter
+ self.plant = plant
+ self.vert = vert
+ self.terr = terr
+
+ self.t_aligns = []
+ self.leng_accum = [0]
+
+ self._init_trans()
+
+ def __getitem__(self, index):
+ return self.t_aligns[index]
+
+ def __setitem__(self, index, value):
+ self.t_aligns[index] = value
+
+ def __delitem__(self, index):
+ del self.t_aligns[index]
+
+ def __len__(self):
+ return len(self.t_aligns)
+
+ def __str__(self):
+ """ Return
+ """
+ string = "[\n"
+ for i in self.t_aligns:
+ string += str(i)
+ string += "]"
+ return string
+
+ def __repr__(self):
+ """ Return
+ """
+ string = "[\n"
+ for i in self.t_aligns:
+ string += str(i)
+ string += "]"
+ return string
+
+ def _init_trans(self):
+ """ Return
+ """
+ dat_1 = []
+ for i, dat_2 in enumerate(self.tabla_iter):
+
+ if i >= 1:
+ if dat_1['npk'] == 0:
+ continue
+ start = dat_1
+ end = dat_2
+
+ r_pnts = self.plant.get_roadpnts(start['pk'], end['pk'],
+ start['npk'], start['npk'])
+ self.vert.set_pnts_elev(r_pnts)
+
+ if self.terr is not None:
+ self.terr.set_pnts_terr(r_pnts)
+
+ for r_pnt in r_pnts:
+
+ dist_left = start['dist_left'] + \
+ ((r_pnt.npk - start['pk']) * (end['dist_left'] -
+ start['dist_left'])) / (end['pk'] - start['pk'])
+
+ dist_right = start['dist_right'] + \
+ ((r_pnt.npk - start['pk']) * (end['dist_right'] -
+ start['dist_right'])) / (end['pk'] - start['pk'])
+
+ trans = TransLine(r_pnt, dist_left, dist_right)
+ self.t_aligns.append(trans)
+ dat_1 = dat_2
+
+ def get_trans(self):
+ """ Return
+ """
+ list_lines = []
+ list_attrs = []
+ for t_ali in self.t_aligns:
+ list_lines.append(t_ali.get_line())
+ list_attrs.append([t_ali.r_pnt.get_pk(),
+ t_ali.r_pnt.get_azi(),
+ t_ali.r_pnt.p_type,
+ round(t_ali.dist_left, 4),
+ round(t_ali.dist_right, 4), ''])
+ return list_lines, list_attrs
+
+ def get_pnts_trans(self, displ):
+ """ Return
+ """
+ list_pnts = []
+ list_attrs = []
+ for t_ali in self.t_aligns:
+ t_ali.set_displ(displ)
+
+# list_pnts.extend(t_ali.displ_left + t_ali.displ_right)
+ for i, r_pnt in enumerate(t_ali.displ_left + t_ali.displ_right):
+ if r_pnt is not None:
+ list_pnts.append(r_pnt)
+ list_attrs.append([r_pnt.get_pk(),
+ r_pnt.get_azi(),
+ t_ali.r_pnt.get_pk(),
+ 'Dist=' +
+ str(round(r_pnt.dist_displ, 4)),
+ 'Displ=' + str(i + 1)])
+
+ return list_pnts, list_attrs
+
+ def get_pnts_trans_terr(self, displ, taludes, terr):
+ """ Return
+ """
+ list_pnts = []
+ list_attrs = []
+ for t_ali in self.t_aligns:
+ t_ali.set_talud(taludes, terr)
+
+ for i, r_pnt in enumerate([t_ali.talud_left, t_ali.talud_right]):
+ if r_pnt is not None and r_pnt.npk != -1:
+
+ list_pnts.append(r_pnt)
+ list_attrs.append([r_pnt.get_pk(),
+ r_pnt.get_azi(),
+ t_ali.r_pnt.get_pk(),
+ 'Dist=' +
+ str(round(r_pnt.dist_displ, 4)),
+ 'Terr=' + str(i + 1)])
+ return list_pnts, list_attrs
+
+ def generate_pks(self, start, end, dpk, mpk, len_d, len_m):
+ """ Return
+ """
+ r_pnts_d = self.plant.get_roadpnts(start, end, dpk, dpk)
+ r_pnts_m = self.plant.get_roadpnts(start, end, mpk, mpk)
+
+ list_trans = []
+ list_attrs = []
+ for r_pnt in r_pnts_d:
+ if r_pnt in r_pnts_m:
+ trans = TransLine(r_pnt, len_m, len_m)
+ else:
+ trans = TransLine(r_pnt, len_d, len_d)
+ list_trans.append(trans.get_line())
+ list_attrs.append([r_pnt.get_pk(), r_pnt.get_azi(), r_pnt.p_type,
+ ''])
+ return list_trans, list_attrs
+
+if __name__ == '__main__':
+ import doctest
+ doctest.testmod()
Property changes on: grass-addons/grass7/vector/v.civil/road_trans.py
___________________________________________________________________
Added: svn:mime-type
+ text/x-python
Added: svn:eol-style
+ native
Added: grass-addons/grass7/vector/v.civil/road_vertical.py
===================================================================
--- grass-addons/grass7/vector/v.civil/road_vertical.py (rev 0)
+++ grass-addons/grass7/vector/v.civil/road_vertical.py 2016-07-01 22:30:22 UTC (rev 68831)
@@ -0,0 +1,338 @@
+# -*- coding: utf-8 -*-
+"""
+Created on Wed Jul 23 20:36:10 2014
+
+ at author: meskal
+"""
+
+#
+# import pygrass modules
+#
+import math
+
+# from grass.pygrass.vector import VectorTopo
+# import road_base as Base
+
+# from grass.pygrass.vector.geometry import Point
+from grass.pygrass.vector.geometry import Line
+
+
+class Parabola(object):
+ """ Return
+ """
+ def __init__(self, k_v=0, pnt_1=None, pnt_v=None, pnt_2=None, plant=None):
+ """ Return
+ """
+ self.k_v = k_v
+ self.pnt_1 = pnt_1
+ self.pnt_v = pnt_v
+ self.pnt_2 = pnt_2
+
+ self.slope_in = self.pnt_1.slope2(self.pnt_v)
+ self.slope_out = self.pnt_v.slope2(self.pnt_2)
+
+ self.pnt_in = pnt_v
+ self.pnt_out = pnt_v
+
+ self._init_align(plant)
+# self.vtype = None
+ self.vert_type()
+
+ def _init_align(self, plant):
+ """ Return
+ """
+ if self.k_v != 0:
+ # B=Kv*phi**2/8
+
+ self.pnt_in = plant.get_roadpoint(self.pnt_v.npk -
+ (self.length() / 2))
+
+ self.pnt_in.z = self.pnt_v.z - self.slope_in * (self.length() / 2)
+
+ self.pnt_out = plant.get_roadpoint(self.pnt_v.npk +
+ (self.length() / 2))
+ self.pnt_out.z = self.pnt_v.z + self.slope_out * (self.length() /
+ 2)
+
+ self.pnt_in.v_param = self.slope_in
+ self.pnt_in.v_type = 'in'
+ self.pnt_v.v_param = self.k_v
+ self.pnt_v.v_type = 'v'
+ self.pnt_out.v_param = self.slope_out
+ self.pnt_out.v_type = 'end'
+
+ def length(self):
+ """ Return
+ """
+ phi = (self.slope_in - self.slope_out)
+ len_tan = self.k_v * phi / 2
+ return 2 * len_tan
+
+ def true_length(self):
+ """ Return
+ """
+ return (self.pnt_2.npk - self.pnt_1.npk) / math.cos(self.slope_in)
+
+ def vert_type(self):
+ """ Return
+ """
+ if self.slope_in < 0 and self.slope_out > 0:
+ return 'Concave'
+ elif self.slope_in > 0 and self.slope_out < 0:
+ return 'Convex'
+ elif self.slope_in >= 0 and self.slope_out > 0:
+ if self.slope_in < self.slope_out:
+ return 'Concave'
+ else:
+ return 'Convex'
+ elif self.slope_in < 0 and self.slope_out <= 0:
+ if self.slope_in > self.slope_out:
+ return 'Concave'
+ else:
+ return 'Convex'
+
+ def grass_rgb(self):
+ """ Return
+ """
+ if self.vert_type() == 'Concave':
+ return '0:255:0'
+ else:
+ return '0:128:0'
+
+ def is_in(self, r_pnt):
+ """ Return
+ """
+ if self.pnt_in.npk <= r_pnt.npk <= self.pnt_out.npk:
+ return True
+ else:
+ return False
+
+ def get_elev(self, r_pnt):
+ """ Return
+ """
+ r_pnt.z = self.pnt_in.z + self.slope_in * \
+ (r_pnt.npk - self.pnt_in.npk) - \
+ (1 / (2 * self.k_v)) * (r_pnt.npk - self.pnt_in.npk) ** 2
+ r_pnt.v_type = self.vert_type()
+ r_pnt.v_param = round(100 * (self.slope_in - (1 / self.k_v) *
+ (r_pnt.npk - self.pnt_in.npk)), 4)
+
+ def get_charact(self):
+ """ Return
+ """
+ return [self.pnt_in, self.pnt_v]
+
+ def get_charact_attrs(self):
+ """ Return
+ """
+ return [[self.pnt_in.get_pk(), self.pnt_in.v_type,
+ round(self.pnt_in.v_param, 4)],
+ [self.pnt_v.get_pk(), self.pnt_v.v_type,
+ round(self.pnt_v.v_param, 4)]]
+
+
+class VStraight(object):
+ """ Return
+ """
+ def __init__(self, pnt_in=None, pnt_out=None):
+ """ Return
+ """
+ self.pnt_in = pnt_in
+ self.pnt_out = pnt_out
+
+ self.slope_in = self.pnt_in.slope2(self.pnt_out)
+ self.pnt_in.v_param = self.slope_in
+ self.pnt_in.v_type = 'in'
+ self.pnt_out.v_param = self.slope_in
+ self.pnt_out.v_type = 'end'
+
+ def length(self):
+ """ Return
+ """
+ return self.pnt_out.npk - self.pnt_in.npk
+
+ def true_length(self):
+ """ Return
+ """
+ return (self.pnt_out.npk - self.pnt_in.npk) / math.cos(self.slope_in)
+
+ def vert_type(self):
+ """ Return
+ """
+ if self.slope_in > 0:
+ return 'Up'
+ else:
+ return 'Down'
+
+ def grass_rgb(self):
+ """ Return
+ """
+ if self.slope_in > 0:
+ return '0:0:255'
+ else:
+ return '255:0:0'
+
+ def is_in(self, r_pnt):
+ """ Return
+ """
+ if round(self.pnt_in.npk, 4) <= round(r_pnt.npk, 4) <= \
+ round(self.pnt_out.npk, 4):
+ return True
+ else:
+ return False
+
+ def get_elev(self, r_pnt):
+ """ Return
+ """
+ r_pnt.z = self.pnt_in.z + self.slope_in * (r_pnt.npk - self.pnt_in.npk)
+ r_pnt.v_type = self.vert_type()
+ r_pnt.v_param = round(100 * self.slope_in, 4)
+
+ def get_charact(self):
+ """ Return
+ """
+ return [self.pnt_in]
+
+ def get_charact_attrs(self):
+ """ Return
+ """
+ return [[self.pnt_in.get_pk(), self.pnt_in.v_type,
+ round(self.pnt_in.v_param, 4)]]
+
+
+# =============================================
+# Vert
+# =============================================
+
+class Vert(object):
+ """ Return
+ """
+ def __init__(self, polygon, tabla_iter, plant):
+ """ Return
+ """
+ self.polygon = polygon
+ self.tabla_iter = tabla_iter
+ self.plant = plant
+
+ self.aligns = []
+ self.leng_accum = [0]
+
+ self._init_vert()
+
+ def __str__(self):
+ """ Return
+ """
+ string = "["
+ for i in self.aligns:
+ string += str(i)
+ string += "]"
+ return string
+
+ def _init_vert(self):
+ """ Return
+ """
+ dat_1 = []
+ dat_2 = []
+ leng_tot = 0
+ for i, dat_3 in enumerate(self.tabla_iter):
+
+ if i == 1:
+ end_pnt = self.plant.get_roadpoint(dat_2['pk'])
+ end_pnt.z = dat_2['elev']
+
+ pnt_2 = self.plant.get_roadpoint(-1)
+ pnt_2.z = dat_3['elev']
+
+ if i >= 2:
+ if i == 2:
+ end_pnt = self.plant.get_roadpoint(dat_1['pk'])
+ end_pnt.z = dat_1['elev']
+
+ pnt_v = self.plant.get_roadpoint(dat_2['pk'])
+ pnt_v.z = dat_2['elev']
+
+ pnt_2 = self.plant.get_roadpoint(dat_3['pk'])
+
+ pnt_2.z = dat_3['elev']
+
+ parabola = Parabola(dat_2['kv'], end_pnt, pnt_v, pnt_2,
+ self.plant)
+
+ straight = VStraight(end_pnt, parabola.pnt_in)
+
+ self.aligns.append(straight)
+ leng_tot += straight.length()
+ self.leng_accum.append(leng_tot)
+
+ self.aligns.append(parabola)
+ leng_tot += parabola.length()
+ self.leng_accum.append(leng_tot)
+
+ end_pnt = parabola.pnt_out
+
+ dat_1 = dat_2
+ dat_2 = dat_3
+
+ if i == len(self.tabla_iter) - 1:
+
+ straight = VStraight(end_pnt, pnt_2)
+ self.aligns.append(straight)
+ leng_tot += straight.length()
+ self.leng_accum.append(leng_tot)
+
+ def set_elev(self, r_pnt):
+ """ Return
+ """
+ for ali in self.aligns:
+ if ali.is_in(r_pnt):
+ ali.get_elev(r_pnt)
+
+ def set_pnts_elev(self, list_r_pnts):
+ """ Return
+ """
+ for r_pnt in list_r_pnts:
+ self.set_elev(r_pnt)
+
+ def set_lines_elev(self, list_r_lines):
+ """ Return
+ """
+ for list_r_lines in list_r_lines:
+ self.set_pnts_elev(list_r_lines)
+
+ def get_segments_pnts(self, list_r_pnts, line=False):
+ """Return
+ """
+ r_lines = []
+ list_attrs = []
+ for ali in self.aligns:
+ pnts_align = [ali.pnt_in]
+ for r_pnt in list_r_pnts:
+ if ali.is_in(r_pnt):
+ pnts_align.append(r_pnt)
+ pnts_align.append(ali.pnt_out)
+ list_attrs.append([ali.pnt_in.get_pk(), ali.vert_type(),
+ round(ali.length(), 4),
+ round(ali.slope_in, 4), ali.grass_rgb()])
+ if line:
+ r_lines.append(Line(pnts_align))
+ else:
+ r_lines.append(pnts_align)
+ return r_lines, list_attrs
+
+ def get_charact_pnts(self):
+ """ Return
+ """
+ list_pnts = []
+ list_attrs = []
+ for ali in self.aligns:
+ list_pnts.extend(ali.get_charact())
+ list_attrs.extend(ali.get_charact_attrs())
+ ali = self.aligns[-1]
+ list_pnts.append(ali.pnt_out)
+ list_attrs.append([ali.pnt_out.get_pk(), ali.pnt_out.v_type,
+ round(ali.pnt_out.v_param, 4)])
+ return list_pnts, list_attrs
+
+if __name__ == '__main__':
+ import doctest
+ doctest.testmod()
Property changes on: grass-addons/grass7/vector/v.civil/road_vertical.py
___________________________________________________________________
Added: svn:mime-type
+ text/x-python
Added: svn:eol-style
+ native
Added: grass-addons/grass7/vector/v.civil/v.road.html
===================================================================
--- grass-addons/grass7/vector/v.civil/v.road.html (rev 0)
+++ grass-addons/grass7/vector/v.civil/v.road.html 2016-07-01 22:30:22 UTC (rev 68831)
@@ -0,0 +1,828 @@
+<!-- <h2>DESCRIPTION</h2> -->
+
+<em>v.civil.road</em> generates a alignment for design roads, channels, ports...
+
+
+<h2>USAGE</h2>
+
+To run the program for the first time, a map with one horizontal polygon, is
+required.
+
+<p>
+There are three options:
+The flag <em>-r</em> for run the program,
+The flag <em>-p</em> Update solution from polygon (if you modific the polygon),
+The flag <em>-t</em> Update solution from table plan (walk with dc_ and lr_)
+
+<p>
+The other options are described below.
+
+
+
+
+<h2>Plan</h2>
+
+<h3>plan options</h3>
+<p>
+<em>plan</em> write the horizontal alignment.
+
+<p>
+<em>pks</em> write pk marks in horizontal.
+
+<p>
+<em>displ</em> write the displaced platform lines in horizontal.
+
+<p>
+<em>marks</em> write the marks in horizontal.
+
+
+<h3>options</h3>
+
+<p>
+<em>pkopt</em> define the distance between normal marks (npk),
+distance between principal marks (mpk), longitude of normal marks and
+longitude of principal marks.
+
+<p>
+<em>areaopt</em> write the areas defined with pairs of displaced lines.
+
+
+
+
+<h2>Vertical</h2>
+
+<h3>vert options</h3>
+<p>
+<em>vert</em> write the vertical alignment in horizontal.
+
+<p>
+<em>profile</em> write longitudinal profile map.
+
+<h3>options</h3>
+<p>
+With the option <em>LPScale</em>, the vertical scale of the longitudinal
+profile can be given.
+
+<p>
+The <em>LPopt</em> option give the longitude of marks, distance between marks
+in axis x and y, and distance between lines of the guitar.
+
+
+
+
+<h2>Cross</h2>
+
+<h3>Cross options</h3>
+<p>
+<em>cross</em> write cross section in horizontal
+
+<p>
+<em>sections</em> write cross sections map.
+
+<h3>options</h3>
+<p>
+With the option <em>LTScale</em>, the vertical scale of the longitudinal
+profile can be given.
+
+<p>
+The <em>LTopt</em> option give the longitude of marks, distance between marks
+in axis x and y, and distance between lines of the guitar.
+
+<p>
+The <em>LTopt2</em> option give the number of rows of cross-section to display,
+distance between cross-section in axis x and y.
+
+
+
+
+
+<h2>Terrain</h2>
+
+<h3>Terr options</h3>
+<p>
+<em>slopes</em> flag write the slope soil lines calculated with the last
+displaced lines (perpendicular to the central axis).
+
+<p>
+<em>sareas</em> write the areas map with slope soil lines and the last
+displaced lines in horizontal.
+
+<p>
+<em>tri</em> write points, lines and hull area map.
+
+
+
+<h2>Tools</h2>
+
+<p>
+The flag <em>-a</em> add a new table. Displ or Marks.
+
+<p>
+The flag <em>-i</em> insert a rows in table. List of pks for each row.
+
+<p>
+The flag <em>-n</em> add a new displ line, ei, a new column in displ table.
+You must give a start and end distances and height. And number of column
+and side to insert.
+
+<p>
+The flag <em>-d</em> del a displ line, ei, a column in displ table. A number
+of column and side is required.
+
+
+<h2>Tables</h2>
+
+<p>
+We have six parts: plant, vertical, displaced, terrain, tranversal and marks.
+
+<p>
+The tables stored in the polygon map are:
+
+<h3>Layer 1:</h3>
+<p>
+Created with only cat column (if not exist), is for free use to add columns
+with information of the road.
+
+
+
+<h3>Layer 2:</h3>
+<p>
+<b>"NameRoad"_Plan</b>, for insert the parameters of the horizontal
+alignment. This layer have all vertices and nodes of the horizontal polygon.
+No more points can be added to this layer with the insert point option.
+
+<p>
+The columns are:
+
+<ul>
+ <li><b>radio</b>: radio of curve
+ <p>+ for clockwise</p>
+ <p>- for anticlockwise</p>
+ </li>
+ <li><b>a_in</b>: Parameter A of input Clothoid</li>
+ <li><b>a_out</b>: Parameter A of output Clothoid</li>
+ <li><b>widening</b>: Widening of curve (where this widening is growing
+ in the clothoid, only in mode exact)</li>
+ <li><b>superelev</b>: Parameter A of input Clothoid</li>
+ <li><b>dc_</b>: longitude of curve. For use with flag <em>-t</em></li>
+ <li><b>lr_</b>: longitude of straight. For use with flag <em>-t</em></li>
+</ul>
+
+
+
+<h3>Layer 3:</h3>
+
+<p>
+<b>"NameRoad"_Vert</b>, for insert the parameters of the vertical
+alignment.This layer are created with the first an last vertices of the
+horizontal polygon. New point can be added by the flag 'e' TableTools option,
+or with edit gui. The added points, are inserted in the central axis
+referencing by pk.
+
+<p>
+The columns are:
+
+<ul>
+ <li><b>pk</b>: kilometric point of the central axis</li>
+ <li><b>elev</b>: Elevation of the vertice of the vertical alignment</li>
+ <li><b>kv</b>: Parameter Kv of the vertical alignment</li>
+ <li><b>l</b>: Leng of parabolic curve (no yet implemented)</li>
+ <li><b>B</b>: Height of vertice of vertical polygon to the parabolic
+ curve (no yet implemented)</li>
+</ul>
+
+
+<h3>Layer 4: </h3>
+
+<b>"NameRoad"_Displ</b>, for insert the parameters of the platform.
+This layer are created with the first an last vertices of the horizontal
+polygon. New point can be added by the flag 'e' TableTools option, or with edit
+gui. The added points, are inserted in the central axis referencing by pk.
+<p>
+The columns for editing by the user are:
+
+<ul>
+ <li><b>pk</b>: kilometric point of the central axis</li>
+ <li><b>sec_left, sec_right</b>: For defining left and right platform lines
+ (distance and height to the central axis), separated by ";" </li>
+ <li><b>type_left, type_right</b>: Types of left and right lines
+ (types are: l,e,r,0). You can enter the type of multiple lines
+ separated by ";"
+ <b>l</b>: linear approximation between definition points.
+ <b>e</b>: displaced lines, mode exact.
+ <b>c</b>: ellipse between definition points.
+ <b>rR,A</b>: circle between definition points ((x-A)^2+y^2=R^2))</li>
+</ul>
+
+<p>
+Between two points, if the second input distance equal zero, the line will be
+stopped. If the second input distance equal -1, this point will not be processed
+and the next one will be considered.
+
+
+
+<h3>Layer 5: </h3>
+
+<b>"NameRoad"_Terr</b>, for insert the parameters for slopes.
+This layer are created with the first an last vertices of the horizontal
+polygon. New point can be added by the flag 'e' TableTools option, or with edit
+gui. The added points, are inserted in the central axis referencing by pk.
+<p>
+The columns for editing by the user are:
+
+<ul>
+ <li><b>cut_left</b>: Cut slope left</li>
+ <li><b>cut_right</b>: Cut slope right</li>
+ <li><b>fill_left</b>: Fill slope left</li>
+ <li><b>fill_right</b>: Fill slope right</li>
+</ul>
+
+
+
+
+<h3>Layer 6:</h3>
+<p>
+<b>"NameRoad"_Trans</b>, for insert the parameters of transects to the central
+axis.
+This layer are created with the first an last vertices of the horizontal
+polygon. New point can be added by the flag 'e' TableTools option, or with edit gui.
+The added points, are inserted in the central axis referencing by pk.
+<p>
+The columns for editing by the user are:
+
+<ul>
+ <li><b>pk</b>: kilometric point of the central axis</li>
+ <li><b>dist_left,dist_right</b>: Distance left and right from the central
+axis</li>
+ <li><b>npk</b>: Distance between trans</li>
+</ul>
+
+
+
+
+<h3>Layer 7:</h3>
+<p>
+<b>"NameRoad"_Marks</b>, for insert the parameters of Marks.
+This layer are created with the first an last vertex of the horizontal
+polygon. New point can be added by the flag 'e' TableTools option, or with edit gui.
+The added points, are inserted in the central axis referencing by pk.
+<p>
+The columns for editing by the user are:
+
+<ul>
+ <li><b>dist</b>: distance left and right from the central axis</li>
+ <li><b>elev</b>: Elevation left and right from the central
+axis</li>
+ <li><b>azi</b>: 1 for azimuth of the point of the road or -1</li>
+ <li><b>name</b>: Name of mark</li>
+ <li><b>cod</b>: Code of mark</li>
+</ul>
+
+
+<h2>Example:</h2>
+
+<p>
+This example is done in the North Carolina data set.
+</p>
+
+<p>
+At the end of this example, there is a backup that can be executed to play with this example.
+</p>
+
+<p>
+The example start creating a closed polygon with the editor, in a created map named Circuit.
+
+<p>
+<img src="./img1.png" width="500" height="406" alt="">
+
+<p>
+After that, run the next command to get all tables in the map Circuit
+
+<pre><code>
+v.road -r name=Circuit
+</code></pre>
+
+<p>
+<img src="./img_tables1.png" width="400" height="166" alt="">
+
+
+<!-- ########################## Plant ############################## -->
+
+<h3>Plant</h3>
+<p>
+For each vertex of the polygon we define a radio and in and out clothoids. So we can write the plant and pks maps.
+
+<p>
+<img src="./img_tables2.png" width="400" height="221" alt="">
+
+<p>
+<img src="./img_a_plan.png" width="300" height="241" alt="">
+
+<pre><code>
+v.road -r name=Circuit plan=plan,pks
+</code></pre>
+
+<p>
+And we obtain the map <em>Circuit__Plant</em> and <em>Circuit__Pks</em>, and their tables.
+
+<p>
+<img src="./img2.png" width="500" height="406" alt="">
+
+<p>
+<img src="./img_tables2_2.png" width="400" height="200" alt="">
+
+<p>
+If we move some vertex of polygon we must run with the flag 'p' to update the road.
+
+<p>
+<img src="./img2_1.png" width="500" height="406" alt="">
+
+<p>
+If we change some values of columns 'dc_' (long of circle) or 'lr_' (long of straight), or fill the last line (with 'dc_' and 'lr_' too,
+a new vertex are inserted and a new line) we must run with the flag 't' to update the road.
+
+<p>
+<img src="./img_tables2_3.png" width="400" height="200" alt="">
+
+<p>
+The distance between points of each alignments is of 1 meters by default, but this can be changed in the Interval in straights and Interval in curves options.
+
+<!-- ########################## Vertical ############################## -->
+
+<h3>Vertical</h3>
+
+At first, we have only the nodes of polygon, and if we set elev we will obtain a straight with slope. To get more
+vertices we have to add new rows to this table with <em>tabletools</em> giving the pk of the vertex.
+
+<p>
+<img src="./img_a_tooladdrow.png" width="300" height="229" alt="">
+
+<p>
+And now we have to set the elevation of those vertices and the <em>kv</em> parameter.
+
+<p>
+<img src="./img_tables3.png" width="400" height="166" alt="">
+
+<p>
+Now choose vertical option to get the vertical map in horizontal and the longitudinal profile, and give a
+<em>DEM</em> in the terrain option.
+
+<pre><code>
+v.road -r name=Circuit vert=vert,profile dem=elev_lid792_1m
+</code></pre>
+
+<p>
+And we obtain the map <em>Circuit__Vertical</em> and <em>Circuit__LongProfile </em>, and their tables.
+
+<p>
+<img src="./img3_2.png" width="500" height="406" alt="">
+
+
+<!-- ########################## Displaced ############################## -->
+
+<h3>Displaced</h3>
+<p>
+For first time, this table have two rows, who are the nodes of the polygon, and for that the first and the last points of the central axis.
+
+<p>
+The displaced lines are defined in sec_left,sec_right columns with a list separated with ";", starting from left to right in each side of the central axis.
+Each displaced line is defined with distance to the central axis and height to the central axis (d,h).
+
+<p>
+The mode to calculate the displaced lines is defined in the type_left,type_right columns,for each line separated by ";".
+
+<p>
+To get more vertices we have to add new rows to this table with <em>tabletools</em> giving the pk of the vertex.
+
+<p>
+In this example we are going to define two displaced lines in the left side to the central axis and two for right side with slope 2% to out.
+
+<p>
+<img src="./img_tables4_1.png" width="400" height="166" alt="">
+
+<p>
+The platform lines define, the lanes of a road, the platform limits, ... Those lines can be parallel to the central axis of a road (or not).
+If it's so, we need to know that the parallel to a clothoid is not a clothoid. Then we have two ways to do the platform lines.
+
+<p>
+In the first way, mode exact "e", we need to calculate a new displaced central axis, e.i., a parallel to the polygon not to the central axis.
+The new alignment or displaced line created within the new polygon have new clothoids for the transitions.
+To run this mode, the first and the last points, of a section of the road, must have the same displaced distance.
+
+<p>
+The widening parameter of the section above, only will be calculate in this mode, because the widening growing in the clothoid,
+then is applied only to the displaced lines calculated with clothoid.
+
+<p>
+The second way, mode lineal "l", we calculate the perpendicular displaced distance to each point of the central axis,
+to obtain a parallel to it, where the transitions won't be clothoids. Then we can't know where are the tangents of transitions.
+But in this mode, the displaced distance for the first and the last points don't have to be the same in a section of the road. A lineal variation will be done between those points.
+
+<p>
+For this example, the first and last are defined as lineal and the rest are in mode exact.
+
+<p>
+Into this second way, the variation don't have to be only lineal. We can define a circumference in the displaced line with the option "rR,A".
+
+<p>
+Between two points, if the second input distance equal zero, the line will be stopped. If the second input distance equal -1, this point will not be processed and the next one will be considered.
+
+<pre><code>
+v.road -r name=Circuit plan=displ
+</code></pre>
+
+And we obtain the map Circuit__Displaced, and their tables.
+
+<p>
+<img src="./img4.png" width="500" height="406" alt="">
+
+<p>
+With distance to the central axis and height of the lines we can obtain different forms, that we'll see in the cross sections.
+
+<p>
+<img src="./img_a_vcivilroad_7.png" width="400" height="200" alt="">
+
+<p>
+Now we can add new lines by hand or with TableTools option.
+
+<pre><code>
+v.road -e name=Circuit displline=add side=left ncol=3 sedist="10 -0.2; 10 -0.2"
+v.road -e name=Circuit displline=add side=right ncol=3 sedist="10 -0.2; 10 -0.2"
+</code></pre>
+
+
+<p>
+And add new points. We are going to cut the last line in pk 900 and 1700.
+
+<pre><code>
+v.road -e name=Circuit at road add=row tab_type=Displ pklist=876,900,1074,1690,1700,1811
+</code></pre>
+
+<p>
+<img src="./img_tables4_2.png" width="400" height="166" alt="">
+
+<p>
+<img src="./img4_1.png" width="500" height="406" alt="">
+
+<p>
+Mode exact "e" in the first two lines, without widening and with widening set to 0.2.
+
+<p>
+<img src="./img4_2.png" width="350" height="275" alt="">
+<img src="./img4_3.png" width="350" height="275" alt="">
+
+
+<!-- ########################## Terr ############################## -->
+
+<h3>Terr</h3>
+
+<p>
+The cut/fill are calculated with the first displaced line of the left side and the last displaced line of the right side,
+and with the slope given in the columns cut_left, cut_right, fill_left, fill_right.
+
+<p>
+To get more vertices we have to add new rows to this table with <em>tabletools</em> giving the pk of the vertex.
+
+<p>
+<img src="./img_tables5_1.png" width="400" height="166" alt="">
+
+<p>
+We can generate points of the different alignments, breaklines and a hull of all points.
+
+<pre><code>
+v.road -r name=Circuit terr=slopes,sareas,topo dem=elev_lid792_1m
+</code></pre>
+
+<p>
+And we obtain the map Circuit__Slopes, Circuit__Slopes_Areas, Circuit__Topo and Circuit__Topo_Hull, and their tables.
+
+<p>
+<img src="./img5.png" width="500" height="406" alt="">
+
+
+
+<!-- ########################## Displaced ############################## -->
+
+<h3>Transversal</h3>
+
+<p>
+In this table where we are going to define transversals 2D lines to the central axis, to obtain later, the cross sections.
+
+<p>
+This lines contains the cutoff with the displaced lines.
+
+<p>
+When this table is created, have two rows, who are the first and the last points of the central axis.
+
+<p>
+In the columns dist_left, dist_right we can define the distance left and right to the central axis and in the column npk the distance between lines.
+
+<p>
+<img src="./img_tables6_1.png" width="400" height="166" alt="">
+
+<p>
+We can obtain the transversal profiles selecting it too.
+
+<pre><code>
+v.road -r name=Circuit trans=trans,profiles dem=elev_lid792_1m
+</code></pre>
+
+<p>
+And we obtain the map Circuit__Trans and Circuit__TransProfiles, and their tables.
+
+<p>
+<img src="./img6.png" width="500" height="406" alt="">
+
+<p>
+<img src="./img6_1.png" width="500" height="406" alt="">
+
+
+<h3>Marks</h3>
+We can define marks or road objects by pk.
+<p>
+<img src="./img_tables7_1.png" width="400" height="166" alt="">
+
+<p>
+<img src="./img7.png" width="500" height="406" alt="">
+
+
+
+<!-- ########################## Displaced ############################## -->
+
+<h3>TopoTools</h3>
+
+<p>
+With the Circuit_Topo map created, we can triangulate with triangle or delaunay, and obtain the curves.
+
+<p>
+In this example we must delete the points that cross the road, for a good triangulation. We can run this.
+
+<pre><code>
+v.edit map=Circuit__Topo type=point tool=delete ids=0-999999 where="pk > 876 AND pk < 1074"
+v.edit map=Circuit__Topo type=point tool=delete ids=0-999999 where="pk > 1690 AND pk < 1811"
+
+db.execute sql="DELETE FROM Circuit__Topo WHERE pk > 876 and pk < 1074"
+db.execute sql="DELETE FROM Circuit__Topo WHERE pk > 1690 and pk < 1811"
+</code></pre>
+
+<p>
+And obtain the Circuit__Topo like this. The hull must be changed too.
+
+
+<p>
+<img src="./img8_1.png" width="500" height="406" alt="">
+
+
+<p>
+<img src="./img_a_topotools_1.png" width="399" height="339" alt="">
+
+<pre><code>
+v.road -o name=Circuit dem=elev_lid792_1m topotools=delaunay,curved,cut_hull
+</code></pre>
+
+<p>
+And we obtain the map Circuit__Topo_Tin and Circuit__Topo_Curves, and their tables.
+
+<p>
+<img src="./img8_2.png" width="500" height="406" alt="">
+
+
+<!-- ########################## Displaced ############################## -->
+
+<h3>Backup</h3>
+
+<p>
+After run the backup you can run this to obtain all maps.
+
+<pre><code>
+v.road -r name=Circuit plan=plan,pks,displ,marks vert=vert,profile trans=trans,profiles terr=slopes,sareas,topo dem=elev_lid792_1m
+</code></pre>
+
+<pre><code>
+echo "L 15 1
+ 638602.453907 220281.587467
+ 638872.438983 220266.927644
+ 638731.321851 220395.256912
+ 638781.230311 220495.669832
+ 638890.64791 220489.728605
+ 638750.420421 220565.326292
+ 638662.05161 220298.095029
+ 638632.866458 220535.678384
+ 638483.222668 220543.750924
+ 638406.451001 220388.023737
+ 638502.195923 220398.284828
+ 638721.795144 220655.135048
+ 638656.193203 220404.828666
+ 638268.15133 220299.739643
+ 638602.453907 220281.587467
+ 1 1
+P 1 1
+ 638602.453907 220281.587467
+ 2 1
+P 1 1
+ 638872.438983 220266.927644
+ 2 2
+P 1 1
+ 638731.321851 220395.256912
+ 2 3
+P 1 1
+ 638781.230311 220495.669832
+ 2 4
+P 1 1
+ 638890.64791 220489.728605
+ 2 5
+P 1 1
+ 638750.420421 220565.326292
+ 2 6
+P 1 1
+ 638662.05161 220298.095029
+ 2 7
+P 1 1
+ 638632.866458 220535.678384
+ 2 8
+P 1 1
+ 638483.222668 220543.750924
+ 2 9
+P 1 1
+ 638406.451001 220388.023737
+ 2 10
+P 1 1
+ 638502.195923 220398.284828
+ 2 11
+P 1 1
+ 638721.795144 220655.135048
+ 2 12
+P 1 1
+ 638656.193203 220404.828666
+ 2 13
+P 1 1
+ 638268.15133 220299.739643
+ 2 14
+P 1 1
+ 638602.453907 220281.587467
+ 2 15
+P 1 1
+ 638602.453907 220281.587467
+ 8 1
+P 1 1
+ 638602.453907 220281.587467
+ 8 2
+P 1 1
+ 638602.453907 220281.587467
+ 4 1
+P 1 1
+ 638634.426432 220500.061126
+ 4 2
+P 1 1
+ 638621.330858 220519.982685
+ 4 3
+P 1 1
+ 638465.368943 220506.786855
+ 4 4
+P 1 1
+ 638666.507984 220451.258691
+ 4 5
+P 1 1
+ 638662.328095 220442.177014
+ 4 6
+P 1 1
+ 638573.410617 220382.409616
+ 4 7
+P 1 1
+ 638602.453907 220281.587467
+ 4 8
+P 1 1
+ 638602.453907 220281.587467
+ 3 1
+P 1 1
+ 638794.637722 220294.628116
+ 3 2
+P 1 1
+ 638791.485541 220543.187779
+ 3 3
+P 1 1
+ 638641.56261 220464.886873
+ 3 4
+P 1 1
+ 638621.266312 220399.660839
+ 3 5
+P 1 1
+ 638406.371565 220315.000175
+ 3 6
+P 1 1
+ 638602.453907 220281.587467
+ 3 7
+P 1 1
+ 638602.453907 220281.587467
+ 7 1
+P 1 1
+ 638634.610948 220499.596419
+ 7 2
+P 1 1
+ 638465.368943 220506.786855
+ 7 3
+P 1 1
+ 638666.507984 220451.258691
+ 7 4
+P 1 1
+ 638654.577521 220429.350321
+ 7 5
+P 1 1
+ 638637.711356 220410.985026
+ 7 6
+P 1 1
+ 638616.836773 220397.342402
+ 7 7
+P 1 1
+ 638593.594427 220388.201219
+ 7 8
+P 1 1
+ 638573.410617 220382.409616
+ 7 9
+P 1 1
+ 638602.453907 220281.587467
+ 7 10
+P 1 1
+ 638602.453907 220281.587467
+ 5 1
+P 1 1
+ 638693.765832 220585.688009
+ 5 2
+P 1 1
+ 638691.041172 220537.792247
+ 5 3
+P 1 1
+ 638535.766657 220372.214897
+ 5 4
+P 1 1
+ 638602.453907 220281.587467
+ 5 5
+P 1 1
+ 638602.453907 220281.587467
+ 6 1
+P 1 1
+ 638602.453907 220281.587467
+ 6 2
+" | v.in.ascii -n input=- output=Circuit format=standard --o
+
+v.db.addtable map=Circuit table=Circuit_Plan layer=2 key=cat2 columns="pk_eje double precision,radio double precision,a_in double precision,a_out double precision,widening double precision,superelev varchar(25),dc_ double precision,lr_ double precision"
+v.db.addtable map=Circuit table=Circuit_Displ layer=8 key=cat8 columns="pk double precision,sec_left varchar(25),sec_right varchar(25),type_left varchar(25),type_right varchar(25)"
+v.db.addtable map=Circuit table=Circuit_Displ layer=4 key=cat4 columns="pk double precision,sec_left varchar(25),sec_right varchar(25),type_left varchar(25),type_right varchar(25)"
+v.db.addtable map=Circuit table=Circuit_Vert layer=3 key=cat3 columns="pk double precision,elev double precision,kv double precision,l double precision,b double precision"
+v.db.addtable map=Circuit table=Circuit_Marks layer=7 key=cat7 columns="pk double precision,dist varchar(25),elev varchar(25),azi varchar(25),name varchar(25),cod varchar(25)"
+v.db.addtable map=Circuit table=Circuit_Terr layer=5 key=cat5 columns="pk double precision,cut_left double precision,cut_right double precision,fill_left double precision,fill_right double precision,height double precision,leng double precision"
+v.db.addtable map=Circuit table=Circuit_Trans layer=6 key=cat6 columns="pk double precision,dist_left double precision,dist_right double precision,npk double precision"
+v.db.addtable map=Circuit table=Circuit layer=1 key=cat columns="name varchar(25)"
+
+echo "UPDATE Circuit_Plan SET pk_eje='0.0',radio='0.0',a_in='0.0',a_out='0.0',widening='0.0',superelev='',dc_='0.0',lr_='140.002162531' WHERE cat2=1;
+UPDATE Circuit_Plan SET pk_eje='270.382786955',radio='-40.0',a_in='35.0',a_out='35.0',widening='0.0',superelev='',dc_='67.689561716',lr_='18.521314174' WHERE cat2=2;
+UPDATE Circuit_Plan SET pk_eje='461.124617255',radio='40.0',a_in='30.0',a_out='30.0',widening='0.0',superelev='',dc_='29.2637172691',lr_='39.7863972502' WHERE cat2=3;
+UPDATE Circuit_Plan SET pk_eje='573.256721368',radio='30.0',a_in='25.0',a_out='25.0',widening='0.0',superelev='',dc_='14.0798000021',lr_='1.81890329525' WHERE cat2=4;
+UPDATE Circuit_Plan SET pk_eje='682.835501948',radio='-15.0',a_in='15.0',a_out='15.0',widening='0.0',superelev='',dc_='25.5209406839',lr_='47.3026773599' WHERE cat2=5;
+UPDATE Circuit_Plan SET pk_eje='842.142623261',radio='-20.0',a_in='20.0',a_out='20.0',widening='0.0',superelev='',dc_='14.9175006172',lr_='100.00718402' WHERE cat2=6;
+UPDATE Circuit_Plan SET pk_eje='1123.60593223',radio='30.0',a_in='25.0',a_out='25.0',widening='0.0',superelev='',dc_='60.1666666667',lr_='24.9072874929' WHERE cat2=7;
+UPDATE Circuit_Plan SET pk_eje='1362.97515278',radio='-60.0',a_in='45.0',a_out='45.0',widening='0.0',superelev='',dc_='49.9304491395',lr_='25.1574394299' WHERE cat2=8;
+UPDATE Circuit_Plan SET pk_eje='1512.8365209',radio='-60.0',a_in='45.0',a_out='45.0',widening='0.0',superelev='',dc_='36.2500000006',lr_='68.9069121541' WHERE cat2=9;
+UPDATE Circuit_Plan SET pk_eje='1686.45923111',radio='-20.0',a_in='20.0',a_out='20.0',widening='0.0',superelev='',dc_='22.711648047',lr_='24.7225033281' WHERE cat2=10;
+UPDATE Circuit_Plan SET pk_eje='1782.75242935',radio='-40.0',a_in='25.0',a_out='25.0',widening='0.0',superelev='',dc_='14.6414158745',lr_='213.435753539' WHERE cat2=11;
+UPDATE Circuit_Plan SET pk_eje='2120.68119964',radio='20.0',a_in='20.0',a_out='20.0',widening='0.0',superelev='',dc_='33.810837057',lr_='71.3354524078' WHERE cat2=12;
+UPDATE Circuit_Plan SET pk_eje='2379.441513',radio='100.0',a_in='75.0',a_out='75.0',widening='0.0',superelev='',dc_='48.75',lr_='140.918379815' WHERE cat2=13;
+UPDATE Circuit_Plan SET pk_eje='2781.46165959',radio='-25.0',a_in='25.0',a_out='25.0',widening='0.0',superelev='',dc_='45.5718116349',lr_='160.427746506' WHERE cat2=14;
+UPDATE Circuit_Plan SET pk_eje='3116.25669305',radio='0.0',a_in='0.0',a_out='0.0',widening='0.0',superelev='',dc_='0.0',lr_='0.0' WHERE cat2=15;
+UPDATE Circuit_Displ SET pk='0.0',sec_left='6 0;3.5 0',sec_right='3.5 0;6 0',type_left='',type_right='' WHERE cat8=1;
+UPDATE Circuit_Displ SET pk='2208.88779535',sec_left='6 0;3.5 0',sec_right='3.5 0;6 0',type_left='',type_right='' WHERE cat8=2;
+UPDATE Circuit_Displ SET pk='0.0',sec_left='10 -0.34;8 -0.19;6.5 -0.13;4 -0.08',sec_right='4 -0.08;6.5 -0.13;8 -0.19;10 -0.34',type_left='l;l;e;e',type_right='e;e;l;l' WHERE cat4=1;
+UPDATE Circuit_Displ SET pk='876.0',sec_left='10 -0.34;-1 0;-1 0;-1 0',sec_right='-1 0;-1 0;-1 0;10 -0.34',type_left='l;l;l;l',type_right='l;l;l;l' WHERE cat4=2;
+UPDATE Circuit_Displ SET pk='900.0',sec_left='0 0;-1 0;-1 0;-1 0',sec_right='-1 0;-1 0;-1 0;0 0',type_left='l;l;l;l',type_right='l;l;l;l' WHERE cat4=3;
+UPDATE Circuit_Displ SET pk='1074.0',sec_left='10 -0.34;-1 0;-1 0;-1 0',sec_right='-1 0;-1 0;-1 0;10 -0.34',type_left='l;l;l;l',type_right='l;l;l;l' WHERE cat4=4;
+UPDATE Circuit_Displ SET pk='1690.0',sec_left='10 -0.34;-1 0;-1 0;-1 0',sec_right='-1 0;-1 0;-1 0;10 -0.34',type_left='l;l;l;l',type_right='l;l;l;l' WHERE cat4=5;
+UPDATE Circuit_Displ SET pk='1700.0',sec_left='0 0;-1 0;-1 0;-1 0',sec_right='-1 0;-1 0;-1 0;0 0',type_left='l;l;l;l',type_right='l;l;l;l' WHERE cat4=6;
+UPDATE Circuit_Displ SET pk='1811.0',sec_left='10 -0.34;-1 0;-1 0;-1 0',sec_right='-1 0;-1 0;-1 0;10 -0.34',type_left='l;l;l;l',type_right='l;l;l;l' WHERE cat4=7;
+UPDATE Circuit_Displ SET pk='2208.88779535',sec_left=' 10 -0.34;8 -0.19;6.5 -0.13;4 -0.08',sec_right='4 -0.08;6.5 -0.13;8 -0.19; 10 -0.34',type_left='l;l;l;l',type_right='l;l;l;l' WHERE cat4=8;
+UPDATE Circuit_Vert SET pk='0.0',elev='118.0',kv='0.0',l='0.0',b='0.0' WHERE cat3=1;
+UPDATE Circuit_Vert SET pk='200.0',elev='116.0',kv='-2500.0',l='0.0',b='0.0' WHERE cat3=2;
+UPDATE Circuit_Vert SET pk='550.0',elev='133.0',kv='3000.0',l='0.0',b='0.0' WHERE cat3=3;
+UPDATE Circuit_Vert SET pk='840.0',elev='114.0',kv='-2000.0',l='0.0',b='0.0' WHERE cat3=4;
+UPDATE Circuit_Vert SET pk='1760.0',elev='133.0',kv='3000.0',l='0.0',b='0.0' WHERE cat3=5;
+UPDATE Circuit_Vert SET pk='2000.0',elev='121.0',kv='-2000.0',l='0.0',b='0.0' WHERE cat3=6;
+UPDATE Circuit_Vert SET pk='2208.88779535',elev='118.0',kv='0.0',l='0.0',b='0.0' WHERE cat3=7;
+UPDATE Circuit_Marks SET pk='0.0',dist='',elev='',azi='',name='',cod='' WHERE cat7=1;
+UPDATE Circuit_Marks SET pk='875.5',dist='0',elev='0',azi='1',name='Bridge1',cod='a1' WHERE cat7=2;
+UPDATE Circuit_Marks SET pk='1074.0',dist='0',elev='0',azi='-1',name='Bridge2',cod='a1' WHERE cat7=3;
+UPDATE Circuit_Marks SET pk='1690.0',dist='0',elev='0',azi='1',name='Tunel1',cod='a2' WHERE cat7=4;
+UPDATE Circuit_Marks SET pk='1715.0',dist='0',elev='0',azi='1',name='Pila',cod='' WHERE cat7=5;
+UPDATE Circuit_Marks SET pk='1740.0',dist='0',elev='0',azi='1',name='Pila',cod='' WHERE cat7=6;
+UPDATE Circuit_Marks SET pk='1765.0',dist='0',elev='0',azi='1',name='Pila',cod='' WHERE cat7=7;
+UPDATE Circuit_Marks SET pk='1790.0',dist='0',elev='0',azi='1',name='Pila',cod='' WHERE cat7=8;
+UPDATE Circuit_Marks SET pk='1811.0',dist='0',elev='0',azi='-1',name='Tunel2',cod='a2' WHERE cat7=9;
+UPDATE Circuit_Marks SET pk='2208.88779535',dist='',elev='',azi='',name='',cod='' WHERE cat7=10;
+UPDATE Circuit_Terr SET pk='0.0',cut_left='2.0',cut_right='2.0',fill_left='0.5',fill_right='0.5',height='0.0',leng='0.0' WHERE cat5=1;
+UPDATE Circuit_Terr SET pk='1550.0',cut_left='2.0',cut_right='2.0',fill_left='0.5',fill_right='0.5',height='0.0',leng='0.0' WHERE cat5=2;
+UPDATE Circuit_Terr SET pk='1600.0',cut_left='2.0',cut_right='2.0',fill_left='4.0',fill_right='4.0',height='0.0',leng='0.0' WHERE cat5=3;
+UPDATE Circuit_Terr SET pk='1850.0',cut_left='2.0',cut_right='2.0',fill_left='0.5',fill_right='0.5',height='0.0',leng='0.0' WHERE cat5=4;
+UPDATE Circuit_Terr SET pk='2208.88779535',cut_left='2.0',cut_right='2.0',fill_left='0.5',fill_right='0.5',height='0.0',leng='0.0' WHERE cat5=5;
+UPDATE Circuit_Trans SET pk='0.0',dist_left='20.0',dist_right='20.0',npk='20.0' WHERE cat6=1;
+UPDATE Circuit_Trans SET pk='2208.88779535',dist_left='20.0',dist_right='20.0',npk='20.0' WHERE cat6=2;
+UPDATE Circuit SET name='Circuit' WHERE cat=1;
+" | db.execute input=-
+</code></pre>
Property changes on: grass-addons/grass7/vector/v.civil/v.road.html
___________________________________________________________________
Added: svn:mime-type
+ text/html
Added: svn:keywords
+ Author Date Id
Added: svn:eol-style
+ native
Added: grass-addons/grass7/vector/v.civil/v.road.py
===================================================================
--- grass-addons/grass7/vector/v.civil/v.road.py (rev 0)
+++ grass-addons/grass7/vector/v.civil/v.road.py 2016-07-01 22:30:22 UTC (rev 68831)
@@ -0,0 +1,832 @@
+#!/usr/bin/env python
+# -*- coding: utf-8
+"""
+Created on Wed Jul 23 18:37:36 2014
+
+ at author: jfcr
+"""
+############################################################################
+#
+# MODULE: v.align, v0.6.0
+#
+# AUTHOR: Jesús Fernández-Capel Rosillo
+# Civil Engineer, Spain
+# jfc at alcd net
+#
+# PURPOSE: Desing roads, channels, ports...
+#
+# COPYRIGHT: (c) 2014 Jesús Fernández-Capel Rosillo.
+#
+# This program is free software under the GNU General Public
+# License (>=v2). Read the file COPYING that comes with GRASS
+# for details.
+#
+#############################################################################
+
+#%Module
+#% description: Generate a alignment for desing roads, channels, ports...
+#% keywords: vector, ROADS, CHANNELS, PORTS.
+#%End
+
+#######################
+### Required section
+#######################
+
+#%option G_OPT_V_INPUT
+#% key: name
+#% type: string
+#% description: Name of road map
+#% required: yes
+#%end
+
+#######################
+### Plant section
+#######################
+
+#%option G_OPT_V_TYPE
+#% key: plan
+#% options: plan,pks,displ,marks
+#% answer:
+#% required: no
+#% description: Plan options
+#% guisection: Plan
+#%end
+
+#%option
+#% key: pkopt
+#% type: string
+#% description: Pks marks options values. (npk,mpk,dist,m)
+#% required: no
+#% answer: 20,100,2,4
+#% guisection: Plan
+#%end
+
+#%option G_OPT_DB_TABLE
+#% key: dtable
+#% description: Other displaced table (Default all)
+#% required: no
+##% guidependency: ocolumn,scolumns
+#% guisection: Plan
+#%end
+
+#%option G_OPT_DB_TABLE
+#% key: mtable
+#% description: Other marks table (Default all)
+#% required: no
+##% guidependency: ocolumn,scolumns
+#% guisection: Plan
+#%end
+
+#%option
+#% key: areaopt
+#% type: string
+#% description: Pair of displaced lines for areas (1-2,2-5,5-6)
+#% required: no
+#% guisection: Plan
+#%end
+
+#######################
+### Alz section
+#######################
+
+#%option G_OPT_V_TYPE
+#% key: vert
+#% options: vert,profile
+#% answer:
+#% required: no
+#% description: Vertical options
+#% guisection: Vert
+#%end
+
+#%option
+#% key: lpscale
+#% type: integer
+#% description: Long profile vertical scale (V/H, V/1)
+#% options: 0-100
+#% answer : 4
+#% required: no
+#% guisection: Vert
+#%end
+
+#%option
+#% key: lpopt
+#% type: string
+#% description: Long profile values Longmark,distMark_x,distMark_y,DistGitarr.
+#% required: no
+#% answer: 2,20,1,20
+#% guisection: Vert
+#%end
+
+#%option
+#% key: lpoffset
+#% type: string
+#% description: Long profile offset from origin of region
+#% required: no
+#% answer: 0,0
+#% guisection: Vert
+#%end
+
+#%option
+#% key: camber
+#% type: string
+#% description: General camber
+#% required: no
+#% answer: 0
+#% guisection: Vert
+#%end
+
+#%option
+#% key: displrot
+#% type: string
+#% description: Displaced lines to rotate
+#% required: no
+#% answer: 0,0
+#% guisection: Vert
+#%end
+
+#######################
+### Trans section
+#######################
+
+#%option G_OPT_V_TYPE
+#% key: trans
+#% options: trans,profiles
+#% answer:
+#% required: no
+#% description: Vertical options
+#% guisection: Trans
+#%end
+
+#%option
+#% key: ltscale
+#% type: double
+#% description: Cross section vertical scale (V/H, V/1)
+#% required: no
+#% answer: 2
+#% guisection: Trans
+#%end
+
+#%option
+#% key: ltopt1
+#% type: string
+#% description: Cross section options values Longmark,distMark_x,distMark_y.
+#% required: no
+#% answer: 1,20,2
+#% guisection: Trans
+#%end
+
+#%option
+#% key: ltopt2
+#% type: string
+#% description: Trans section options values for nrows,distTP_x,distTP_y.
+#% required: no
+#% answer: 10,10,10
+#% guisection: Trans
+#%end
+
+#%option
+#% key: ltoffset
+#% type: string
+#% description: Trans sections profile offset from origin of region
+#% required: no
+#% answer: 0,0
+#% guisection: Trans
+#%end
+
+#########################
+### Terrain section
+#########################
+
+#%option G_OPT_V_TYPE
+#% key: terr
+#% options: slopes,sareas,topo
+#% answer:
+#% required: no
+#% description: Terrain options
+#% guisection: Terr
+#%end
+
+#%option G_OPT_R_INPUT
+#% key: dem
+#% key_desc: raster dem
+#% description: Name of DEM raster
+#% required: no
+#% guisection: Terr
+#%end
+
+#########################
+### TopoTools section
+#########################
+
+#%flag
+#% key: o
+#% description: TopoTools
+#% guisection: TopoTools
+#%end
+
+#%option G_OPT_V_TYPE
+#% key: actions
+#% options: uppoints, pnt_info
+#% answer:
+#% required: no
+#% description: Points tools
+#% guisection: TopoTools
+#%end
+
+#%option
+#% key: pk_info
+#% type: double
+#% description: PK
+#% required: no
+#% answer: 0
+#% guisection: TopoTools
+#%end
+
+#%option G_OPT_V_TYPE
+#% key: topotools
+#% options: triangle,delaunay,curved,cut_hull
+#% answer:
+#% required: no
+#% description: Triangulate and curved
+#% guisection: TopoTools
+#%end
+
+##%option G_OPT_V_TYPE
+##% key: tinraster
+##% options: tintorast,nnbathy
+##% answer:
+##% required: no
+##% description: Triangulate and curved
+##% guisection: TopoTools
+##%end
+
+
+#%option G_OPT_V_TYPE
+#% key: roundabout
+#% options: roundabout
+#% answer:
+#% required: no
+#% description: Roundabout tools
+#% guisection: TopoTools
+#%end
+
+#%option
+#% key: rround1
+#% type: string
+#% description: Minus radio for roundabout edge
+#% required: no
+#% guisection: TopoTools
+#%end
+
+#%option
+#% key: rround2
+#% type: string
+#% description: Mayor radio for roundabout edge
+#% required: no
+#% guisection: TopoTools
+#%end
+
+#%option
+#% key: azround
+#% type: string
+#% description: Azimut for roundabout start point
+#% required: no
+#% guisection: TopoTools
+#%end
+
+#%option
+#% key: cround
+#% type: string
+#% description: Center for roundabout
+#% required: no
+#% guisection: TopoTools
+#%end
+
+#%option
+#% key: roundname
+#% type: string
+#% description: Name for roundabout
+#% required: no
+#% guisection: TopoTools
+#%end
+
+#########################
+### TableTools section
+#########################
+
+#%flag
+#% key: e
+#% description: TableTools
+#% guisection: TableTools
+#%end
+
+#%option G_OPT_V_TYPE
+#% key: add
+#% options: table, row
+#% answer:
+#% required: no
+#% description: Add new table or add row to table
+#% guisection: TableTools
+#%end
+
+#%option
+#% key: tab_type
+#% type: string
+#% label: Name of table for new table or to add row
+#% description: To add new table only Displ or Marks table are supported
+#% options: Vert,Displ,Trans,Terr,Marks
+#% required: no
+#% guisection: TableTools
+#%end
+
+#%option
+#% key: tab_subname
+#% type: string
+#% label: Table subname for new table or row or displ subname to add or del col
+#% required: no
+#% guisection: TableTools
+#%end
+
+#%option
+#% key: pklist
+#% type: string
+#% label: List of Pks
+#% required: no
+#% guisection: TableTools
+#%end
+
+#%option G_OPT_V_TYPE
+#% key: displline
+#% options: add,del
+#% answer:
+#% required: no
+#% description: Add or del displaced line
+#% guisection: TableTools
+#%end
+
+#%option
+#% key: side
+#% type: string
+#% label: left or right side of Displ
+#% options: left,right
+#% required: no
+#% guisection: TableTools
+#%end
+
+#%option
+#% key: ncol
+#% type: integer
+#% label: Number of Displ to insert
+#% required: no
+#% guisection: TableTools
+#%end
+
+#%option
+#% key: sedist
+#% type: string
+#% label: start and end distance and height
+#% required: no
+#% guisection: TableTools
+#%end
+
+#########################
+### CrossTools section
+#########################
+
+#%flag
+#% key: c
+#% description: CrossTools
+#% guisection: CrossTools
+#%end
+
+#%option G_OPT_V_TYPE
+#% key: intersect
+#% options: left1, right1, left2, right2, in, out, rounda, write
+#% answer:
+#% required: no
+#% description: Plan options
+#% guisection: CrossTools
+#%end
+
+#%option G_OPT_V_INPUT
+#% key: plant1
+#% key_desc: map plant 1
+#% description: Name of first map plant
+#% required: no
+#% guisection: CrossTools
+#%end
+
+#%option
+#% key: cat1
+#% type: integer
+#% label: Categorie of align
+#% required: no
+#% answer: 1
+#% guisection: CrossTools
+#%end
+
+
+#%option G_OPT_V_INPUT
+#% key: plant2
+#% key_desc: map plant 2
+#% description: Name of second map plant
+#% required: no
+#% guisection: CrossTools
+#%end
+
+#%option
+#% key: cat2
+#% type: integer
+#% label: Categorie of align
+#% required: no
+#% answer: 1
+#% guisection: CrossTools
+#%end
+
+#%option
+#% key: dist1
+#% type: string
+#% description: Displaced distances for aling 1
+#% required: no
+#% guisection: CrossTools
+#%end
+
+#%option
+#% key: dist2
+#% type: string
+#% description: Displaced distances for aling 2
+#% required: no
+#% guisection: CrossTools
+#%end
+
+#%option
+#% key: radios
+#% type: string
+#% description: Intersections radios
+#% required: no
+#% guisection: CrossTools
+#%end
+
+#########################
+### #Options section
+#########################
+
+#%flag
+#% key: r
+#% description: Run
+#%end
+
+#%flag
+#% key: p
+#% description: Update solution from polygon
+#%end
+
+#%flag
+#% key: t
+#% description: Update solution from table plan distances_
+#%end
+
+#%option
+#% key: intr
+#% type: integer
+#% label: Interval in straights
+#% required: no
+#% answer: 1
+#%end
+
+#%option
+#% key: intc
+#% type: integer
+#% label: Interval in curves
+#% required: no
+#% answer: 1
+#%end
+
+#%option
+#% key: startend
+#% type: string
+#% label: start and end pks (last pk = -1)
+#% required: no
+#% answer: 0,-1
+#%end
+
+#%option G_OPT_F_OUTPUT
+#% key: backup
+#% description: Create backup file
+#% required: no
+#%end
+
+# ######################
+
+import os
+import sys
+
+sys.path.insert(1, os.path.join(os.path.dirname(sys.path[0]), 'etc', 'v.road'))
+
+# import math
+# import road as Road
+import grass.script as grass
+import road_road as Road
+import road_crosstools as Tools2
+import road_topotools as Topotools
+
+
+# =============================================
+# Main
+# =============================================
+
+def main():
+ """Manage v.road
+ >>> road = Road.Road('Circuit')
+ >>>
+
+ """
+ if '@' in options['name']:
+ name_map = options['name'].split('@')[0]
+ else:
+ name_map = options['name']
+
+ plan_opt = options['plan'].split(',')
+ vert_opt = options['vert'].split(',')
+ trans_opt = options['trans'].split(',')
+ terr_opt = options['terr'].split(',')
+
+ add = options['add'].split(',')
+ displline = options['displline'].split(',')
+
+ intersect = options['intersect'].split(',')
+ topotools = options['topotools'].split(',')
+ actions = options['actions'].split(',')
+ roundabout = options['roundabout'].split(',')
+ # tinraster = options['tinraster'].split(',')
+
+ startend = [float(opt) for opt in options['startend'].split(',')]
+ pkopt = [float(opt) for opt in options['pkopt'].split(',')]
+
+ if options['tab_subname']:
+ options['tab_subname'] = '_' + options['tab_subname']
+
+ if options['tab_type']:
+ options['tab_type'] = '_' + options['tab_type']
+
+### Init road
+ road = Road.Road(name_map)
+
+################### TableTools ##################
+
+ if flags['e']:
+ # Insert new point
+ if 'row' in add:
+
+ road.plant_generate()
+
+ if ',' in options['pklist']:
+ list_pks = options['pklist'].split(',')
+ else:
+ list_pks = [options['pklist']]
+
+ road.rtab.add_row(list_pks, road.plant, options['tab_type'],
+ options['tab_subname'])
+ sys.exit(0)
+
+ # Add new table
+ if 'table' in add:
+ road.rtab.add_table(options['tab_type'], options['tab_subname'])
+ sys.exit(0)
+
+ # Add column to Displ table
+ if 'add' in displline or 'del' in displline:
+ add_col = True
+ if 'del' in displline:
+ add_col = False
+ road.rtab.tables['_Displ' + options['tab_subname']].displ_add_del_col(
+ options['ncol'], options['side'], options['sedist'], add_col)
+ sys.exit(0)
+
+################### CrossTools ##################
+
+ if flags['c']:
+ inout = 'In'
+ if 'out' in intersect:
+ inout = 'Out'
+ rounda = False
+ if 'rounda' in intersect:
+ rounda = True
+ izq1 = 'Izq'
+ if 'right1' in intersect:
+ izq1 = 'Der'
+ izq2 = 'Izq'
+ if 'right2' in intersect:
+ izq2 = 'Der'
+
+ if '@' in options['plant1']:
+ name_plant1 = options['plant1'].split('@')[0]
+ else:
+ name_plant1 = options['plant1']
+
+ if '@' in options['plant2']:
+ name_plant2 = options['plant2'].split('@')[0]
+ else:
+ name_plant2 = options['plant2']
+
+ inter = Tools2.Intersections(name_plant1, int(options['cat1']), izq1,
+ name_plant2, int(options['cat2']), izq2,
+ inout, rounda)
+ inter.dist2 = [float(p) for p in options['dist2'].split(',')]
+ inter.dist1 = [float(p) for p in options['dist1'].split(',')]
+ inter.radios = [float(p) for p in options['radios'].split(',')]
+
+ if 'write' in intersect:
+ inter.make_intersect(True)
+ else:
+ inter.make_intersect()
+ sys.exit(0)
+
+################### Topotools ##################
+
+ if flags['o']:
+ if actions != ['']:
+ if 'uppoints' in actions:
+ topo = Topotools.Topo(name_map)
+ topo.uppoints()
+
+ if roundabout != ['']:
+ if 'roundabout' in roundabout:
+ topo = Topotools.Topo(options['roundname'])
+ topo.roundabout(options['rround1'], options['rround1'],
+ options['azround'], options['cround'])
+
+ if topotools != ['']:
+ tri = Topotools.Triang(name_map)
+ if 'triangle' in topotools:
+ tri.split_maps()
+ tri.triangle()
+ elif 'delaunay' in topotools:
+ tri.delaunay()
+ tri.get_area_hull()
+ if 'curved' in topotools:
+ tri.curved()
+ if 'cut_hull' in topotools:
+ tri.cut_by_hull()
+
+ # if tinraster != ['']:
+ # tin = Topotools.Triang(name_map)
+ # if 'tintorast' in tinraster:
+ # tin.tin_to_raster()
+ # if 'nnbathy' in tinraster:
+ # tin.nnbathy()
+
+ else:
+ sys.exit(0)
+
+################### Backup ##################
+
+ if options['backup']:
+ road.rtab.create_backup(options['backup'])
+ grass.message('backup created')
+ sys.exit(0)
+
+##################### Run ###################
+
+ if flags['r']:
+
+ if flags['t']:
+ road.plant_generate(True, float(options['camber']))
+ road.rtab.update_tables()
+ elif flags['p']:
+ road.plant_generate(False, float(options['camber']))
+ road.rtab.update_tables()
+ else:
+ road.plant_generate(False, float(options['camber']))
+
+ if 'plan' in plan_opt:
+ road.rtab.update_tables_pnts(road.plant)
+
+ road.elev_generate()
+
+ road.displ_generate()
+
+ if options['dem']:
+
+ road.terr_generate(options['dem'])
+
+ road.taludes_generate()
+
+ road.trans_generate()
+
+ if 'profile' in vert_opt:
+ road.long_profile_generate(options['lpopt'],
+ options['lpscale'],
+ options['lpoffset'])
+
+ if 'profiles' in trans_opt:
+ road.trans_profiles_generate(options['ltopt1'],
+ options['ltopt2'],
+ options['ltscale'],
+ options['ltoffset'])
+ else:
+ road.trans_generate()
+
+ if 'marks' in plan_opt:
+ road.marks_generate()
+
+### Write maps
+
+ if flags['o']:
+ if actions != ['']:
+ if 'pnt_info' in actions:
+ pto_inf = Topotools.Topo(name_map)
+ pto_inf.pts_info(options['pk_info'], road)
+ sys.exit(0)
+
+ #
+ road.plant.set_roadline(startend[0], startend[1],
+ float(options['intr']), float(options['intc']))
+ road.plant.add_pks(road.rtab.get_tables_pks())
+
+ road.vert.set_pnts_elev(road.plant.roadline)
+
+ road.displ.set_roadlines(road.plant.roadline)
+
+ #
+ if 'plan' in plan_opt:
+ grass.message('writing plan')
+ road.plant_write()
+
+ if 'displ' in plan_opt:
+ grass.message('writing displ')
+ road.displ_write()
+
+ if 'marks' in plan_opt:
+ grass.message('writing marks')
+ road.marks_write()
+
+ if 'pks' in plan_opt:
+ grass.message('writing pks')
+ road.trans_write_pks(startend, pkopt)
+
+ #
+ if 'vert' in vert_opt:
+ grass.message('writing elev')
+ road.elev_write()
+
+ #
+ if 'trans' in trans_opt:
+ grass.message('writing trans')
+ road.trans_write()
+
+ if options['dem']:
+
+ road.terr.set_pnts_terr(road.plant.roadline)
+
+ road.taludes.set_roadlines(road.plant.roadline, road.displ)
+
+ #
+ if 'profile' in vert_opt:
+ grass.message('writing profile')
+ road.long_profile_write()
+
+ if 'profiles' in trans_opt:
+ grass.message('writing profiles')
+ road.trans_profiles_write()
+
+ #
+ if 'slopes' in terr_opt:
+ grass.message('writing slopes')
+ road.taludes_write()
+
+ if 'sareas' in terr_opt:
+ grass.message('writing slopes_areas')
+ road.taludes_areas_write()
+
+ if 'topo' in terr_opt:
+ grass.message('writing pnts, breakliness and hull for \
+ triangulation')
+ road.tri_write()
+
+ tab_subname_d = ''
+ if options['dtable']:
+ tab_subname_d = options['dtable'].split('_Displ')[-1]
+ road.displ_generate(tab_subname_d)
+ road.displ.set_roadlines(road.plant.roadline)
+ road.displ_write('_' + tab_subname_d)
+
+ if options['mtable']:
+ road.marks_generate(options['mtable'])
+ tab_subname_m = '_' + options['mtable'].split('_Marks')[-1]
+ road.marks_write(tab_subname_m)
+
+ if options['areaopt']:
+ grass.message('writing displ_areas')
+ road.displ_areas_write(options['areaopt'], tab_subname_d)
+
+ sys.exit(0)
+
+if __name__ == "__main__":
+ if len(sys.argv) == 2 and sys.argv[1] == '--doctest':
+ import doctest
+ doctest.testmod()
+
+ else:
+ options, flags = grass.parser()
+ main()
Property changes on: grass-addons/grass7/vector/v.civil/v.road.py
___________________________________________________________________
Added: svn:mime-type
+ text/x-python
Added: svn:eol-style
+ native
More information about the grass-commit
mailing list