GISLoader.js 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. /**
  2. * GISLoader.js
  3. *
  4. * @author realor
  5. */
  6. import { ObjectBuilder } from '../../builders/ObjectBuilder.js'
  7. import { Solid } from '../../core/Solid.js'
  8. import { SolidGeometry } from '../../core/SolidGeometry.js'
  9. import { Profile } from '../../core/Profile.js'
  10. import { CircleBuilder } from '../../builders/CircleBuilder.js'
  11. import { ProfileGeometry } from '../../core/ProfileGeometry.js'
  12. import { Cord } from '../../core/Cord.js'
  13. import { CordGeometry } from '../../core/CordGeometry.js'
  14. import { Extruder } from '../../builders/Extruder.js'
  15. import { Formula } from '../../formula/Formula.js'
  16. import { ColladaLoader } from '../ColladaLoader.js'
  17. import * as THREE from '../../lib/three.module.js'
  18. class GISLoader extends THREE.Loader {
  19. constructor(manager, mimeType) {
  20. super(manager)
  21. this.options = {}
  22. this.mimeType = mimeType
  23. this.origin = new THREE.Vector3()
  24. this.materials = new Map()
  25. /* default material for Cords and Profiles */
  26. this.lineMaterial = new THREE.LineBasicMaterial({ color: 0x0 })
  27. }
  28. load(url, onLoad, onProgress, onError) {
  29. const options = this.options
  30. this.representation = options.representation
  31. if (options.origin) {
  32. this.origin.copy(options.origin)
  33. }
  34. const request = new XMLHttpRequest()
  35. request.open('GET', url, true)
  36. if (options.username && options.password) {
  37. const basicAutho = 'Basic ' + window.btoa(options.username + ':' + options.password)
  38. request.setRequestHeader('Authorization', basicAutho)
  39. }
  40. request.onreadystatechange = () => {
  41. if (request.readyState === 4) {
  42. if (request.status === 0 || request.status === 200 || request.status === 207) {
  43. let featureGroup = this.parse(request.responseXML ? request.responseXML : request.responseText)
  44. onLoad(featureGroup)
  45. }
  46. }
  47. }
  48. request.send()
  49. }
  50. parse(
  51. data // abstract
  52. ) {}
  53. createObject(type, name, coordinates, properties, parent) {
  54. try {
  55. if (type === 'Point') {
  56. this.createPoint(name, coordinates, properties, parent)
  57. } else if (type === 'MultiPoint') {
  58. this.createMultiPoint(name, coordinates, properties, parent)
  59. } else if (type === 'LineString') {
  60. this.createLineString(name, coordinates, properties, parent)
  61. } else if (type === 'MultiLineString') {
  62. this.createMultiLineString(name, coordinates, properties, parent)
  63. } else if (type === 'Polygon') {
  64. this.createPolygon(name, coordinates, properties, parent)
  65. } else if (type === 'MultiPolygon') {
  66. this.createMultiPolygon(name, coordinates, properties, parent)
  67. } else {
  68. this.createNonVisibleObject(name, properties, parent)
  69. }
  70. } catch (ex) {
  71. console.warn(ex)
  72. }
  73. }
  74. createNonVisibleObject(name, properties, parent) {
  75. let object = new THREE.Object3D()
  76. this.setObjectProperties(object, name, properties)
  77. parent.add(object)
  78. }
  79. setObjectProperties(object, name, properties) {
  80. object.name = name
  81. if (properties) {
  82. object.userData.GIS = properties
  83. }
  84. }
  85. createPoint(name, coordinates, properties, parent) {
  86. let object = null
  87. if (this.representation instanceof THREE.Object3D) {
  88. object = this.representation.clone()
  89. object.userData.selection = { group: true }
  90. } else {
  91. // default shape: cylinder
  92. let profile = new Profile()
  93. profile.builder = new CircleBuilder(0.5)
  94. profile.name = 'Profile'
  95. let solid = new Solid()
  96. solid.add(profile)
  97. solid.builder = new Extruder(1)
  98. ObjectBuilder.build(solid)
  99. object = solid
  100. }
  101. object.visible = true
  102. object.position.x = coordinates[0]
  103. object.position.y = coordinates[1]
  104. object.position.z = coordinates.length === 3 ? coordinates[2] : 0
  105. object.position.sub(this.origin)
  106. this.setObjectProperties(object, name, properties)
  107. parent.add(object)
  108. Formula.updateTree(object)
  109. ObjectBuilder.build(object)
  110. object.updateMatrix()
  111. }
  112. createMultiPoint(name, coordinates, properties, parent) {
  113. let group = new THREE.Group()
  114. this.setObjectProperties(group, name, properties)
  115. for (let i = 0; i < coordinates.length; i++) {
  116. let pointCoords = coordinates[i]
  117. this.createPoint(name + '_' + i, pointCoords, null, group)
  118. }
  119. group.userData.selection = { group: true }
  120. parent.add(group)
  121. }
  122. createLineString(name, coordinates, properties, parent) {
  123. let vertices = []
  124. for (let i = 0; i < coordinates.length; i++) {
  125. let point = coordinates[i]
  126. let v = new THREE.Vector3(point[0], point[1], point.length === 3 ? point[2] : 0)
  127. v.sub(this.origin)
  128. vertices.push(v)
  129. }
  130. let geometry = new CordGeometry(vertices)
  131. let cord = new Cord(geometry, this.lineMaterial)
  132. let solid = null
  133. if (this.representation instanceof Solid) {
  134. solid = this.representation.clone()
  135. solid.add(cord)
  136. cord.visible = false
  137. }
  138. const object = solid || cord
  139. object.visible = true
  140. this.setObjectProperties(object, name, properties)
  141. parent.add(object)
  142. Formula.updateTree(object)
  143. ObjectBuilder.build(object)
  144. object.updateMatrix()
  145. }
  146. createMultiLineString(name, coordinates, properties, parent) {
  147. let group = new THREE.Group()
  148. this.setObjectProperties(group, name, properties)
  149. for (let i = 0; i < coordinates.length; i++) {
  150. let polygonCoords = coordinates[i]
  151. this.createLineString(name + '_' + i, polygonCoords, null, group)
  152. }
  153. parent.add(group)
  154. }
  155. createPolygon(name, coordinates, properties, parent) {
  156. let pts = []
  157. let outerRing = coordinates[0]
  158. for (let p = 0; p < outerRing.length - 1; p++) {
  159. let point = outerRing[p]
  160. let v = new THREE.Vector2(point[0], point[1])
  161. v.sub(this.origin)
  162. pts.push(v)
  163. }
  164. let shape = new THREE.Shape(pts)
  165. // holes
  166. let holes = shape.holes
  167. for (let r = 1; r < coordinates.length; r++) {
  168. let innerRing = coordinates[r]
  169. pts = []
  170. for (let p = 0; p < innerRing.length - 1; p++) {
  171. let point = innerRing[p]
  172. let v = new THREE.Vector2(point[0], point[1])
  173. v.sub(this.origin)
  174. pts.push(v)
  175. }
  176. holes.push(new THREE.Shape(pts))
  177. }
  178. let geometry = new ProfileGeometry(shape)
  179. let profile = new Profile(geometry, this.lineMaterial)
  180. let solid = null
  181. if (this.representation instanceof Solid) {
  182. solid = this.representation.clone()
  183. solid.add(profile)
  184. profile.visible = false
  185. }
  186. let object = solid || profile
  187. object.visible = true
  188. this.setObjectProperties(object, name, properties)
  189. parent.add(object)
  190. Formula.updateTree(object)
  191. ObjectBuilder.build(object)
  192. object.updateMatrix()
  193. }
  194. createMultiPolygon(name, coordinates, properties, parent) {
  195. let group = new THREE.Group()
  196. this.setObjectProperties(group, name, properties)
  197. for (let i = 0; i < coordinates.length; i++) {
  198. let polygonCoords = coordinates[i]
  199. this.createPolygon(name + '_' + i, polygonCoords, null, group)
  200. }
  201. parent.add(group)
  202. }
  203. }
  204. export { GISLoader }