HT for Web, en tant que composant graphique de topologie logique, ne possède pas de fonctions SIG en soi, mais il peut être intégré à divers moteurs SIG, c'est-à-dire ses composants clients, pour obtenir une intégration transparente de la topologie logique et de la topologie physique. Ce chapitre présentera en détail les points techniques clés de l'application combinée de HT pour le Web et du développement de cartes OpenLayers gratuites. Les principes de la combinaison introduits dans cet article peuvent en fait être étendus à des solutions intégrées à de nombreux moteurs de cartes SIG tels que ArcGIS, Cartes Baidu et Google Maps.
La capture d'écran ci-dessus est le dernier effet d'exécution de l'exemple présenté dans cet article. Ensuite, nous l'implémenterons étape par étape. nécessite des données de longitude et de latitude de la ville, Recherche Merci pour les données fournies par ce blog. Pour une si grande quantité de données, j'utilise la méthode getRawTextfunction introduite dans "HT Graphic Component Design (4)". Après avoir obtenu les données, le seul problème est la présentation. Nous devons utiliser GraphView de HT. Le composant est superposé au composant de carte d'OpenLayers, c'est-à-dire que l'image de la carte de tuiles d'OpenLayers est en bas et le composant de GraphView est en haut. Puisque GraphView est transparent par défaut, les utilisateurs des éléments non graphiques peuvent voir la carte. contenu à travers lui. Trouver l'emplacement d'insertion approprié pour les composants est un véritable casse-tête. Presque tous les composants SIG d'ArcGIS, Baidu Maps, y compris Google Maps, nécessitent quelques tentatives pour trouver l'emplacement d'insertion approprié. L'intégration d'autres composants du moteur SIG sera présentée dans les chapitres suivants. Dans cet article, nous nous concentrons sur la méthode d'insertion d'OpenLayers est map.viewPortp.appendChild(graphView.getView()).
Une fois les composants HT et OpenLayers superposés, le problème restant est la combinaison du placement des primitives dans la topologie et de la longitude et de la latitude stockées dans ht.Node dans le réseau conventionnel. Le diagramme de topologie est la position logique. Cela n'a rien à voir avec la longitude et la latitude, donc dans les applications SIG, nous devons convertir les informations de coordonnées logiques de l'écran en fonction des informations de longitude et de latitude de l'élément graphique si vous connaissez l'algorithme de projection. , vous pouvez également fournir le traitement des fonctions vous-même, mais tous les composants SIG fournissent des fonctions d'appel similaires. Bien sûr, cette partie n'est pas standardisée pour appeler des API différentes, mais le principe de base est le même. nous pouvons convertir les informations de latitude et de longitude en pixels de l'écran via map.getPixelFromLonLat(data.lonLat) Coordonnées logiques, c'est-à-dire les informations de coordonnées de position requises par ht.Node.
Les étudiants prudents penseront que la conversion est bidirectionnelle. Il est possible que l'utilisateur doive faire glisser le nœud primitif pour modifier ses informations de longitude et de latitude. À ce stade, nous avons besoin d'une autre fonction de direction, qui est. pour convertir les coordonnées logiques de l'écran en coordonnées actuelles. La longitude et la latitude, dans OpenLayers, nous pouvons les obtenir via map.getLonLatFromPixel(new OpenLayers.Pixel(x, y));
Une fois l'affichage terminé, le seul problème restant est l'interaction. HT a son propre système d'interaction, et OpenLayers a également besoin d'une itinérance sur la carte et d'une interaction avec le zoom. Comment combiner les deux ? Il serait préférable que les fonctions des deux puissent être conservées. La réponse est oui, il suffit d'ajouter la surveillance des événements mousedown ou touchstart. Si graphView.getDataAt(e) sélectionne l'élément graphique, nous l'arrêterons via e.stopPropagation(. ); Propagation de l'événement, de sorte que la map map ne réponde pas. À ce moment, HT prend en charge l'interaction. Si l'élément n'est pas sélectionné, map prend en charge l'interaction de l'opération map.
La conception d'interaction ci-dessus semble parfaite, mais pendant le fonctionnement, j'ai trouvé plusieurs pièges qui m'ont mis beaucoup de temps à trouver la solution :
Configuration de map.events. fallThrough = true ; sinon, la carte ne transmettra pas les événements de manière transparente au composant GraphView de HT
graphView.getView().style.zIndex = 999 ; Vous devez spécifier un certain zIndex, sinon ce sera le cas. bloqué
graphView.getView().className = 'olScrollable'; Sinon, la molette de défilement ne répondra pas au zoom de la carte
Set ht. Default.baseZIndex : 1000 Sinon, la ToolTip sera masquée
Afin de rendre cet exemple plus convivial, j'ai également soigneusement bricolé quelques points techniques pour référence :
Adopté La bibliothèque de couleurs open source gratuite llllll.li/randomColor/random possède de nombreuses fonctions d'acquisition de couleurs intéressantes. J'affiche simplement différentes couleurs pour chaque province
Surchargé. isVisible, isNoteVisible et isLabelVisible pour afficher un contenu plus détaillé uniquement lorsque le zoom atteint un certain niveau. Sinon, toutes les informations sur la ville seront affichées et complètement invisibles lors d'un zoom arrière. Cela peut améliorer les performances d'affichage dans une certaine mesure
.
function init(){ graphView = new ht.graph.GraphView(); var view = graphView.getView(); map = new OpenLayers.Map("map"); var ol_wms = new OpenLayers.Layer.WMS( "OpenLayers WMS", "http://vmap0.tiles.osgeo.org/wms/vmap0", {layers: "basic"} ); map.addLayers([ol_wms]); map.addControl(new OpenLayers.Control.LayerSwitcher()); map.zoomToMaxExtent(); map.events.fallThrough = true; map.zoomToProxy = map.zoomTo; map.zoomTo = function (zoom,xy){ view.style.opacity = 0; map.zoomToProxy(zoom, xy); console.log(zoom); }; map.events.register("movestart", this, function() { }); map.events.register("move", this, function() { }); map.events.register("moveend", this, function() { view.style.opacity = 1; reset(); }); graphView.getView().className = 'olScrollable'; graphView.setScrollBarVisible(false); graphView.setAutoScrollZone(-1); graphView.handleScroll = function(){}; graphView.handlePinch = function(){}; graphView.mi(function(e){ if(e.kind === 'endMove'){ graphView.sm().each(function(data){ if(data instanceof ht.Node){ var position = data.getPosition(), x = position.x + graphView.tx(), y = position.y + graphView.ty(); data.lonLat = map.getLonLatFromPixel(new OpenLayers.Pixel(x, y)); } }); } }); graphView.enableToolTip(); graphView.getToolTip = function(event){ var data = this.getDataAt(event); if(data){ return '城市:' + data.s('note') + ' 经度:' + data.lonLat.lon + ' 维度:' + data.lonLat.lat; } return null; }; graphView.isVisible = function(data){ return map.zoom > 1 || this.isSelected(data); }; graphView.isNoteVisible = function(data){ return map.zoom > 6 || this.isSelected(data); }; graphView.getLabel = function(data){ return '经度:' + data.lonLat.lon + '\n维度:' + data.lonLat.lat; }; graphView.isLabelVisible = function(data){ return map.zoom > 7 || this.isSelected(data); }; view.addEventListener("ontouchend" in document ? 'touchstart' : 'mousedown', function(e){ var data = graphView.getDataAt(e); if(data || e.metaKey || e.ctrlKey){ e.stopPropagation(); } }, false); view.style.position = 'absolute'; view.style.top = '0'; view.style.left = '0'; view.style.right = '0'; view.style.bottom = '0'; view.style.zIndex = 999; map.viewPortp.appendChild(view); var color = randomColor(); lines = china.split('\n'); for(var i=0; i<lines.length; i++) { line = lines[i].trim(); if(line.indexOf('【') === 0){ //province = line.substring(1, line.length-1); color = randomColor(); }else{ var ss = line.split(' '); if(ss.length === 3){ createNode(parseFloat(ss[1].substr(3)), parseFloat(ss[2].substr(3)), ss[0].substr(3), color); } } } } function reset(){ graphView.tx(0); graphView.ty(0); graphView.dm().each(function(data){ if(data.lonLat){ data.setPosition(map.getPixelFromLonLat(data.lonLat)); } }); graphView.validate(); } function createNode(lon, lat, name, color){ var node = new ht.Node(); node.s({ 'shape': 'circle', 'shape.background': color, 'note': name, 'label.background': 'rgba(255, 255, 0, 0.5)', 'select.type': 'circle' }); node.setSize(10, 10); var lonLat = new OpenLayers.LonLat(lon, lat); lonLat.transform('EPSG:4326', map.getProjectionObject()); node.setPosition(map.getPixelFromLonLat(lonLat)); node.lonLat = lonLat; graphView.dm().add(node); return node; }
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!