Skip to content

Commit

Permalink
Support for hover and click events in geodata (#3)
Browse files Browse the repository at this point in the history
* click and hover events in geodata implemented
  • Loading branch information
davidmtech authored Mar 27, 2017
1 parent 0a89854 commit 6b711a6
Show file tree
Hide file tree
Showing 11 changed files with 150 additions and 79 deletions.
Empty file modified .gitignore
100644 → 100755
Empty file.
8 changes: 6 additions & 2 deletions src/core/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -241,12 +241,16 @@ Melown.Core.prototype.on = function(name_, listener_) {


// private
Melown.Core.prototype.callListener = function(name_, event_) {
Melown.Core.prototype.callListener = function(name_, event_, log_) {
for (var i = 0; i < this.listeners_.length; i++) {
if (this.listeners_[i].name_ == name_) {
this.listeners_[i].listener_(event_);
}
}

if (log_) {
console.log("event " + name_ + ": " + JSON.stringify(event_));
}
};

// private
Expand All @@ -268,7 +272,7 @@ string getCoreVersion()
*/

Melown.getCoreVersion = function(full_) {
return (full_ ? "Core: " : "") + "1.94";
return (full_ ? "Core: " : "") + "1.95";
};


Expand Down
12 changes: 6 additions & 6 deletions src/core/map/draw.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Melown.Map.prototype.draw = function(skipFreeLayers_, projected_, camInfo_) {
var cameraPos_ = this.cameraPosition_;

if (this.freeLayersHaveGeodata_ && this.drawChannel_ == 0) {
this.renderer_.drawGpuJobs();
this.renderer_.clearJobBuffer();
}

if (this.drawEarth_) {
Expand Down Expand Up @@ -99,8 +99,8 @@ Melown.Map.prototype.draw = function(skipFreeLayers_, projected_, camInfo_) {
if ((this.replay_.drawFreeTiles_ && this.replay_.drawnFreeTiles_) ||
(this.replay_.drawLoaded_ && this.replay_.loaded_)) {

if (this.freeLayersHaveGeodata_) {
this.renderer_.clearJobBuffer();
if (this.freeLayersHaveGeodata_ && this.drawChannel_ == 0) {
this.renderer_.drawGpuJobs();
}
}

Expand Down Expand Up @@ -150,7 +150,7 @@ Melown.Map.prototype.draw = function(skipFreeLayers_, projected_, camInfo_) {
for (var i = 0, li = this.freeLayerSequence_.length; i < li; i++) {
var layer_ = this.freeLayerSequence_[i];
if (layer_.ready_ && layer_.tree_ &&
(!layer_.geodata_ || (layer_.stylesheet_ && layer_.stylesheet_.isReady())) ) {
(!layer_.geodata_ || (layer_.stylesheet_ && layer_.stylesheet_.isReady())) && this.drawChannel_ == 0) {

if (layer_.type_ == "geodata") {
this.drawMonoliticGeodata(layer_);
Expand Down Expand Up @@ -303,8 +303,8 @@ Melown.Map.prototype.draw = function(skipFreeLayers_, projected_, camInfo_) {
}
}*/

if (this.freeLayersHaveGeodata_) {
this.renderer_.clearJobBuffer();
if (this.freeLayersHaveGeodata_ && this.drawChannel_ == 0) {
this.renderer_.drawGpuJobs();
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/core/map/geodata-processor/worker-linestring.js
Original file line number Diff line number Diff line change
Expand Up @@ -532,7 +532,8 @@ var processLineStringPass = function(lineString_, lod_, style_, zIndex_, eventIn
type_: messageData_["type"],
color_ : lineColor_,
zIndex_ : zIndex_,
zOffset_ : zbufferOffset_
zOffset_ : zbufferOffset_,
state_ : hitState_
});

if (normalBuffer_) {
Expand Down
83 changes: 46 additions & 37 deletions src/core/map/geodata-processor/worker-main.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,32 +31,27 @@ var processLayerFeaturePass = function(type_, feature_, lod_, layer_, zIndex_, e

};

var processLayerFeature = function(type_, feature_, lod_, layer_, featureIndex_) {
//var layer_ = getLayer(feature_["style"], type_, featureIndex_);
var visible_ = getLayerPropertyValue(layer_, "visible", feature_, lod_);
var zIndex_ = getLayerPropertyValue(layer_, "z-index", feature_, lod_);

if (visible_ == false) {
return;
}

var eventInfo_ = feature_.properties_;
var processFeature = function(type_, feature_, lod_, featureIndex_, featureType_, group_) {

//loop layers
for (var key_ in stylesheetLayers_) {
var layer_ = stylesheetLayers_[key_];
var filter_ = getLayerPropertyValue(layer_, "filter", feature_, lod_);

var hoverLayerId_ = getLayerPropertyValue(layer_, "hover-style", feature_, lod_);
var hoverlayer_ = (hoverLayerId_ != "") ? getLayer(hoverLayerId_, type_, featureIndex_) : null;
feature_.properties_ = feature_["properties"] || {};

if (hoverlayer_ != null) {
hitState_ = 1;
processLayerFeaturePass(type_, feature_, lod_, layer_, zIndex_, eventInfo_);
hitState_ = 2;
processLayerFeaturePass(type_, feature_, lod_, hoverlayer_, zIndex_, eventInfo_);
} else {
hitState_ = 0;
processLayerFeaturePass(type_, feature_, lod_, layer_, zIndex_, eventInfo_);
if (feature_["id"]) {
feature_.properties_["#id"] = feature_["id"];
}

if (!filter_ || getFilterResult(filter_, feature_, featureType_, group_)) {
processLayerFeature(type_, feature_, lod_, layer_, featureIndex_);
}
}
}


var multiPass_ = getLayerPropertyValue(layer_, "next-pass", feature_, lod_);
var processLayerFeatureMultipass = function(type_, feature_, lod_, layer_, featureIndex_, eventInfo_) {
var multiPass_ = getLayerPropertyValue(layer_, "next-pass", feature_, lod_);

if (multiPass_ != null) {
for (var i = 0, li = multiPass_.length; i < li; i++) {
Expand All @@ -69,37 +64,51 @@ var processLayerFeature = function(type_, feature_, lod_, layer_, featureIndex_)
continue;
}

hoverLayerId_ = getLayerPropertyValue(layer_, "hover-style", feature_, lod_);
hoverLayerId_ = getLayerPropertyValue(layer_, "hover-layer", feature_, lod_);
hoverlayer_ = (hoverLayerId_ != "") ? getLayer(hoverLayerId_, type_, featureIndex_) : null;

if (hoverlayer_ != null) {
var lastHitState_ = hitState_;
hitState_ = 1;
processLayerFeaturePass(type_, feature_, lod_, layer_, zIndex_, eventInfo_);
hitState_ = 2;
processLayerFeaturePass(type_, feature_, lod_, hoverlayer_, zIndex_, eventInfo_);
hitState_ = lastHitState_;
} else {
hitState_ = 0;
//hitState_ = 0;
processLayerFeaturePass(type_, feature_, lod_, layer_, zIndex_, eventInfo_);
}
}
}

};

var processFeature = function(type_, feature_, lod_, featureIndex_, featureType_, group_) {

//loop layers
for (var key_ in stylesheetLayers_) {
var layer_ = stylesheetLayers_[key_];
var filter_ = getLayerPropertyValue(layer_, "filter", feature_, lod_);

feature_.properties_ = feature_["properties"] || {};

if (!filter_ || getFilterResult(filter_, feature_, featureType_, group_)) {
processLayerFeature(type_, feature_, lod_, layer_, featureIndex_);
}
var processLayerFeature = function(type_, feature_, lod_, layer_, featureIndex_) {
//var layer_ = getLayer(feature_["style"], type_, featureIndex_);
var visible_ = getLayerPropertyValue(layer_, "visible", feature_, lod_);
var zIndex_ = getLayerPropertyValue(layer_, "z-index", feature_, lod_);

if (visible_ == false) {
return;
}

var eventInfo_ = feature_.properties_;

var hoverLayerId_ = getLayerPropertyValue(layer_, "hover-layer", feature_, lod_);
var hoverlayer_ = (hoverLayerId_ != "") ? getLayer(hoverLayerId_, type_, featureIndex_) : null;

if (hoverlayer_ != null) {
hitState_ = 1;
processLayerFeaturePass(type_, feature_, lod_, layer_, zIndex_, eventInfo_);
processLayerFeatureMultipass(type_, feature_, lod_, layer_, featureIndex_, eventInfo_);
hitState_ = 2;
processLayerFeaturePass(type_, feature_, lod_, hoverlayer_, zIndex_, eventInfo_);
processLayerFeatureMultipass(type_, feature_, lod_, hoverlayer_, featureIndex_, eventInfo_);
} else {
hitState_ = 0;
processLayerFeaturePass(type_, feature_, lod_, layer_, zIndex_, eventInfo_);
processLayerFeatureMultipass(type_, feature_, lod_, layer_, featureIndex_, eventInfo_);
}

};


Expand Down
8 changes: 4 additions & 4 deletions src/core/map/geodata-processor/worker-style.js
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ var inheritLayer = function(layerId_, layer_, layerData_, stylesheetLayersData_,
//do we need inherite Layer?
if (layerData_["inherit"] != null) {
//get inherited Layer
var LayerToInherit_ = stylesheetLayersData_["Layers"][layerData_["inherit"]];
var LayerToInherit_ = stylesheetLayersData_["layers"][layerData_["inherit"]];

if (LayerToInherit_ != null) {

Expand Down Expand Up @@ -379,7 +379,7 @@ var validateValue = function(layerId_, key_, value_, type_, arrayLength_, min_,
typeof valueItem_[0] == "number" &&
typeof valueItem_[1] == "string") {

if (stylesheetLayersData_["Layers"][valueItem_[1]] == null) {
if (stylesheetLayersData_["layers"][valueItem_[1]] == null) {

}

Expand Down Expand Up @@ -551,7 +551,7 @@ var validateLayerPropertyValue = function(layerId_, key_, value_) {
case "zbuffer-offset": return validateValue(layerId_, key_, value_, "object", 3, 0, Number.MAX_VALUE); break;

case "hover-event": return validateValue(layerId_, key_, value_, "boolean"); break;
case "hover-style": return validateValue(layerId_, key_, value_, "string"); break;
case "hover-layer": return validateValue(layerId_, key_, value_, "string"); break;
case "enter-event": return validateValue(layerId_, key_, value_, "boolean"); break;
case "leave-event": return validateValue(layerId_, key_, value_, "boolean"); break;
case "click-event": return validateValue(layerId_, key_, value_, "boolean"); break;
Expand Down Expand Up @@ -617,7 +617,7 @@ var getDefaultLayerPropertyValue = function(key_) {
case "zbuffer-offset": return [0,0,0];

case "hover-event": return false;
case "hover-style": return "";
case "hover-layer": return "";
case "enter-event": return false;
case "leave-event": return false;
case "click-event": return false;
Expand Down
4 changes: 2 additions & 2 deletions src/core/map/interface.js
Original file line number Diff line number Diff line change
Expand Up @@ -376,11 +376,11 @@ Melown.MapInterface.prototype.getStats = function() {
};

Melown.MapInterface.prototype.click = function(screenX_, screenY_, state_) {
map_.click(screenX_, screenY_, state_);
this.map_.click(screenX_, screenY_, state_);
};

Melown.MapInterface.prototype.hover = function(screenX_, screenY_, persistent_, state_) {
map_.hover(screenX_, screenY_, persistent_, state_);
this.map_.hover(screenX_, screenY_, persistent_, state_);
};

Melown.MapPositionInterface = Melown.MapPosition;
Expand Down
56 changes: 40 additions & 16 deletions src/core/map/map.js
Original file line number Diff line number Diff line change
Expand Up @@ -936,25 +936,46 @@ Melown.Map.prototype.getHitCoords = function(screenX_, screenY_, mode_, lod_) {
Melown.Map.prototype.hitTestGeoLayers = function(screenX_, screenY_, mode_) {
if (this.geoHitMapDirty_) {
if (this.freeLayersHaveGeodata_) {
this.renderer_.gpu_.setState(this.drawTileState_);
this.renderer_.switchToFramebuffer("geo");
//this.renderer_.onlyHitLayers_ = true;
this.renderer_.drawGpuJobs();
//this.renderer_.onlyHitLayers_ = false;
this.renderer_.switchToFramebuffer("base");
this.geoHitMapDirty_ = false;
}
}

if (!this.freeLayersHaveGeodata_) {
this.lastHoverFeature_ = null;
this.lastHoverFeatureId_ = null;
this.hoverFeature_ = null;
this.hoverFeatureId_ = null;

return [null, false, []];
}

var res_ = this.renderer_.hitTestGeoLayers(screenX_, screenY_, mode_);

if (res_[0]) { //do we hit something?
//console.log(JSON.stringify([id_, JSON.stringify(this.hoverFeatureList_[id_])]));

var id_ = (res_[1]) + (res_[2]<<8);
var elementId_ = (res_[3]) + (res_[4]<<8);

var feature_ = this.hoverFeatureList_[id_];

if (mode_ == "hover") {
this.lastHoverFeature_ = this.hoverFeature_;
this.lastHoverFeatureId_ = this.hoverFeatureId_;
this.hoverFeature_ = null;
this.hoverFeatureId_ = null;
this.hoverFeature_ = this.hoverFeatureList_[id_];
this.hoverFeatureId_ = (this.hoverFeature_ != null) ? this.hoverFeature_[0]["id"] : null;

if (feature_ && feature_[3] == true) {
this.hoverFeature_ = feature_;
this.hoverFeatureId_ = (feature_ != null) ? feature_[0]["#id"] : null;
} else {
this.hoverFeature_ = null;
this.hoverFeatureId_ = null;
}

var relatedEvents_ = [];

Expand All @@ -971,18 +992,17 @@ Melown.Map.prototype.hitTestGeoLayers = function(screenX_, screenY_, mode_) {
}

if (this.hoverFeature_ != null && this.hoverFeature_[3] == true) {
return [this.hoverFeature_, surfaceHit_, relatedEvents_];
return [this.hoverFeature_, true, relatedEvents_];
} else {
return [null, false, relatedEvents_];
}
}

if (mode_ == "click") {
var feature_ = this.hoverFeatureList_[id_];
//this.hoverFeatureId_ = (this.hoverFeature_ != null) ? this.hoverFeature_["id"] : null;

if (feature_ != null && this.hoverFeature_ != null && this.hoverFeature_[2] == true) {
return [feature_, surfaceHit_, []];
if (feature_ != null && feature_[2] == true) {
return [feature_, true, []];
} else {
return [null, false, []];
}
Expand Down Expand Up @@ -1032,6 +1052,10 @@ Melown.Map.prototype.drawMap = function() {
this.renderer_.dirty_ = true;
this.renderer_.drawFog_ = this.drawFog_;

this.renderer_.hoverFeatureCounter_ = 0;
this.renderer_.hoverFeatureList_ = this.hoverFeatureList_;
this.renderer_.hoverFeature_ = this.hoverFeature_;

this.renderer_.cameraPosition_ = this.cameraPosition_;
this.renderer_.cameraOrientation_ = this.position_.getOrientation();
this.renderer_.cameraTiltFator_ = Math.cos(Melown.radians(this.renderer_.cameraOrientation_[1]));
Expand Down Expand Up @@ -1180,8 +1204,8 @@ Melown.Map.prototype.update = function() {
var result_ = this.hitTestGeoLayers(this.hoverEvent_[0], this.hoverEvent_[1], "hover");

if (result_[1] == true && result_[0] != null) {
this.core_.callListener("geo-feature-hover", {"feature": result_[0][0], "screen-pos":this.project(result_[0][1]),
"scene-pos":result_[0][1], "state": this.hoverEvent_[3] });
this.core_.callListener("geo-feature-hover", {"feature": result_[0][0], "canvas-coords":this.renderer_.project2(result_[0][1], this.camera_.getMvpMatrix()),
"camera-coords":result_[0][1], "state": this.hoverEvent_[3] }, true);
}

var relatedEvents_ = result_[2];
Expand All @@ -1192,13 +1216,13 @@ Melown.Map.prototype.update = function() {

switch(event_[0]) {
case "enter":
this.core_.callListener("geo-feature-enter", {"feature": event_[0], "screen-pos":this.project(event_[1]),
"scene-pos":event_[1], "state": this.hoverEvent_[3] });
this.core_.callListener("geo-feature-enter", {"feature": event_[1][0], "canvas-coords":this.renderer_.project2(event_[1][1], this.camera_.getMvpMatrix()),
"camera-coords":event_[1][1], "state": this.hoverEvent_[3] }, true);
break;

case "leave":
this.core_.callListener("geo-feature-leave", {"feature":event_[0], "screen-pos":this.project(event_[1]),
"scene-pos":event_[1], "state": this.hoverEvent_[3] });
this.core_.callListener("geo-feature-leave", {"feature":event_[1][0], "canvas-coords":this.renderer_.project2(event_[1][1], this.camera_.getMvpMatrix()),
"camera-coords":event_[1][1], "state": this.hoverEvent_[3] }, true);
break;
}
}
Expand All @@ -1214,8 +1238,8 @@ Melown.Map.prototype.update = function() {
var result_ = this.hitTestGeoLayers(this.clickEvent_[0], this.clickEvent_[1], "click");

if (result_[1] == true && result_[0] != null) {
this.core_.callListener("geo-feature-click", {"feature": result_[0][0], "screen-pos":this.project(result_[0][1]),
"scene-pos":result_[0][1], "state": this.hoverEvent_[3] });
this.core_.callListener("geo-feature-click", {"feature": result_[0][0], "canvas-coords":this.renderer_.project2(result_[0][1], this.camera_.getMvpMatrix()),
"camera-coords":result_[0][1], "state": this.clickEvent_[2] }, true);
}

this.clickEvent_ = null;
Expand Down
17 changes: 14 additions & 3 deletions src/core/renderer/draw.js
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,8 @@ Melown.Renderer.prototype.drawGpuJobs = function() {

Melown.StencilLineState_ = this.gpu_.createState({blend_:true, stencil_:true, culling_: false});
Melown.LineLabelState_ = this.gpu_.createState({blend_:true, culling_: false});
Melown.StencilLineHitState_ = this.gpu_.createState({blend_:false, stencil_:true, culling_: false});
Melown.LineLabelHitState_ = this.gpu_.createState({blend_:false, culling_: false});

var screenPixelSize_ = [1.0/this.curSize_[0], 1.0/this.curSize_[1]];

Expand Down Expand Up @@ -629,9 +631,18 @@ Melown.Renderer.prototype.drawGpuJobs = function() {
}
}

for (var j = 0; j < lj; j++) {
Melown.drawGpuJob(gpu_, gl_, this, buffer_[j], screenPixelSize_);
//buffer_[j] = null;

if (this.onlyHitLayers_) {
for (var j = 0; j < lj; j++) {
if (buffer_[j].hitable_) {
Melown.drawGpuJob(gpu_, gl_, this, buffer_[j], screenPixelSize_);
}
}
} else {
for (var j = 0; j < lj; j++) {
Melown.drawGpuJob(gpu_, gl_, this, buffer_[j], screenPixelSize_);
//buffer_[j] = null;
}
}

//this.jobZBufferSize_[i] = 0;
Expand Down
Loading

0 comments on commit 6b711a6

Please sign in to comment.