module TerraHS.TerraLib.TeGeometryAlgorithms where
import Foreign (unsafePerformIO)
import Foreign.C.String
import qualified Foreign.Ptr (Ptr)
--locais
import TerraHS.Algebras.Base.Object
import TerraHS.TerraLib.TeGeometry
import TerraHS.TerraLib.TePoint
import TerraHS.TerraLib.TeLine2D
import TerraHS.TerraLib.TeCell
import TerraHS.TerraLib.TeBox
import TerraHS.TerraLib.TePolygon
import TerraHS.Algebras.Base.Operations
import TerraHS.Algebras.Spatial.Geometries
instance Centroid TePointSet TePoint where
centroid ps = unsafePerformIO ( ( new ps ) >>= tepointset_tefindcentroid >>= fromPointer >>= return )
instance Centroid TeLineSet TePoint where
centroid ls = unsafePerformIO ( ( new ls ) >>= telineset_tefindcentroid >>= fromPointer >>= return )
instance Centroid TePolygonSet TePoint where
centroid pols = unsafePerformIO ( ( new pols ) >>= tepolygonset_tefindcentroid >>= fromPointer >>= return )
instance Centroid TePolygon TePoint where
centroid pols = unsafePerformIO ( ( new pols ) >>= tepolygon_tefindcentroid >>= fromPointer >>= return )
instance DistanceDirection TePoint where
distance p1 p2 = tedistance p1 p2
instance Numeric TePolygon where
area p = tearea p
length pol = telength (head (getlines pol) )
where
getlines (TePolygon ls) = ls
instance Numeric TeBox where
area p = teareabox p
instance Numeric TeLine2D where
length l = telength l
tedistance pt1 pt2 = ( unsafePerformIO (applyf pt1 toTE pt2 toTE tepoint_tedistance))
where
toTE tx = new tx
telength :: TeLine2D -> Double
telength l = ( unsafePerformIO (new l >>= \tl -> h_telength tl >>= \r -> delete tl >> return r ))
tearea :: TePolygon -> Double
tearea p = ( unsafePerformIO (new p >>= \tpol -> (tegeometryarea tpol) >>= \r -> delete tpol >> return r ))
teareabox :: TeBox -> Double
teareabox p = ( unsafePerformIO (new p >>= \tb -> tegeometryareabox tb >>= \r -> delete tb >> return r ))
makepolygon box = unsafePerformIO ( (new box ) >>= (temakepolygon) >>= fromPointer >>= return )
tepolygonrotate pol1 angle= unsafePerformIO ((new pol1) >>= \tpol1 -> (tepolygon_rotate tpol1 angle) >>= fromPointer >>= \r -> delete tpol1 >> return r)
tepolygonradius pol1 = unsafePerformIO ((new pol1) >>= \tpol1 -> (tepolygon_radius tpol1 ) >>= \r -> delete tpol1 >> return r)
tepolygonrectangularfit pol1 = unsafePerformIO ((new pol1) >>= \tpol1 -> (tepolygon_rectangularfit tpol1 ) >>= \r -> delete tpol1 >> return r)
tebufferregion :: TePolygon -> Double -> Int -> [TeGeometry]
tebufferregion pol distance npoints = unsafePerformIO (tebufferregion')
where
tebufferregion' = do
ptrpol <- (new pol)
ptrpolset <- (h_tebufferregion ptrpol distance npoints)
(polset2geoset ptrpolset)
polset2geoset gs = size gs >>= (polygonset2geometryset gs 0)
instance Set TePolygon where
union p1 p2
| (r == [] ) = error "union: return any geometry"
| otherwise = head r
where
r = (union [p1] [p2])
difference p1 p2 = head (difference [p1] [p2])
intersection p1 p2 = head (intersection [p1] [p2])
instance Set [TeGeometry] where
union gs1 gs2 = unsafePerformIO (apply1 gs1 gs2 (\ptr1 ptr2 -> teoverlay ptr1 ptr2 2))
difference gs1 gs2 = unsafePerformIO (apply1 gs1 gs2 (\ptr1 ptr2 -> teoverlay ptr1 ptr2 1))
intersection gs1 gs2 = unsafePerformIO (apply1 gs1 gs2 (\ptr1 ptr2 -> teoverlay ptr1 ptr2 4))
instance Set TePolygonSet where
union gs1 gs2 = (TePolygonSet (map toPolygon (unsafePerformIO (apply gs1 gs2 (\ptr1 ptr2 -> teoverlay ptr1 ptr2 2)))))
difference gs1 gs2 = (TePolygonSet (map toPolygon (unsafePerformIO (apply gs1 gs2 (\ptr1 ptr2 -> teoverlay ptr1 ptr2 1)))))
difference gs1 gs2 = (TePolygonSet (map toPolygon (unsafePerformIO (apply gs1 gs2 (\ptr1 ptr2 -> teoverlay ptr1 ptr2 4)))))
instance Set [TePolygon] where
union p1 p2 = geos
where
(TePolygonSet geos) = union (TePolygonSet p1) (TePolygonSet p2)
intersection a b = geos
where
(TePolygonSet geos) = intersection (TePolygonSet a) (TePolygonSet b)
difference a b = geos
where
(TePolygonSet geos) = difference (TePolygonSet a) (TePolygonSet b)
apply1 gs1 gs2 f = (new (TePolygonSet (map toPolygon1 gs1))) >>= \ps1 -> (new (TePolygonSet (map toPolygon1 gs2))) >>= \ps2 -> f ps1 ps2 >>= \geo -> polset2geoset geo >>= return
where
polset2geoset gs = size gs >>= (polygonset2geometryset gs 0)
toPolygon1 (GPg pg) = pg
apply gs1 gs2 f = (new gs1) >>= \ps1 -> (new gs2) >>= \ps2 -> f ps1 ps2 >>= \geo -> polset2geoset geo >>= return
where
polset2geoset gs = size gs >>= (polygonset2geometryset gs 0)
foreign import stdcall unsafe "c_teoverlay" teoverlay :: TePolygonSetPtr -> TePolygonSetPtr -> Int -> Prelude.IO TePolygonSetPtr
foreign import stdcall unsafe "c_tepoint_tedistance" tepoint_tedistance :: TePointPtr -> TePointPtr -> Prelude.IO Double
foreign import stdcall unsafe "c_telength" h_telength :: TeLine2DPtr -> Prelude.IO Double
foreign import stdcall unsafe "c_tegeometryarea" tegeometryarea :: TePolygonPtr -> Prelude.IO Double
foreign import stdcall unsafe "c_tegeometryareabox" tegeometryareabox :: TeBoxPtr -> Prelude.IO Double
foreign import stdcall unsafe "c_tepointset_tefindcentroid" tepointset_tefindcentroid :: TePointSetPtr -> Prelude.IO TePointPtr
foreign import stdcall unsafe "c_tepolygonset_tefindcentroid" tepolygonset_tefindcentroid :: TePolygonSetPtr -> Prelude.IO TePointPtr
foreign import stdcall unsafe "c_telineset_tefindcentroid" telineset_tefindcentroid :: TeLineSetPtr -> Prelude.IO TePointPtr
foreign import stdcall unsafe "c_tepolygon_tefindcentroid" tepolygon_tefindcentroid :: TePolygonPtr -> Prelude.IO TePointPtr
foreign import stdcall unsafe "c_set_precision" setPrecision :: Double -> Prelude.IO ()
foreign import stdcall unsafe "c_tebufferregion" h_tebufferregion :: TePolygonPtr -> Double -> Int -> Prelude.IO TePolygonSetPtr
foreign import stdcall unsafe "c_temakepolygon" temakepolygon :: TeBoxPtr -> Prelude.IO TePolygonPtr
foreign import stdcall unsafe "c_tepolygon_rotate" tepolygon_rotate :: TePolygonPtr -> Double -> Prelude.IO TePolygonPtr
foreign import stdcall unsafe "c_tepolygon_angle" tepolygon_angle :: TePolygonPtr -> Prelude.IO Double
foreign import stdcall unsafe "c_tepolygon_radius" tepolygon_radius :: TePolygonPtr -> Prelude.IO Double
foreign import stdcall unsafe "c_tepolygon_rectangularfit" tepolygon_rectangularfit :: TePolygonPtr -> Prelude.IO Double