Git Product home page Git Product logo

ofxvectortile's Introduction

No Maintenance Intended

VectorTile

This addon is a wrapper from a Mapzen Tangram experiment on 3D Labels

Install

Install addons dependences:

	cd openFrameworks/addons
	git clone --depth 1 http://github.com/patriciogonzalezvivo/ofxGlmTools.git
	git clone --depth 1 http://github.com/jefftimesten/ofxJSON.git

Add to project

Install ofxVectorTile to your project using the ProjectGenerator, dragging folder or Adam’s OFPlugin.

On the project Properties (the blue icons with the name of your project) go to Building Settings > Linking > Other Linker Flags and add -lcurl

Dependences

Sources

The Problem

Labels in maps are a huge headache, and have been for a long time. There are lots of solutions for 2D mapping, but not so many when you work in 3D, and especially not when your map shifts between 2D and 3D.

The Experiments

The main trick is a 2D projection of the geometry to place the text, within the canvas. Like a heads-up display layer between the 3D geometry and the camera.

In the canvas: projection

Pros:

  • Fonts don’t need to be resized on zoom

  • No off-screen computations

  • We know exactly what the user sees

Cons:

  • Occlusion becomes a problem: Should labels be visible through buildings? Which labels to prioritize, how to prioritize them? For now, these have no occlusion.

Line Labels

  • Fit and repeat
	float lastSeed = 0.0;
	for (int i = 0; i < _anchorLine.size()-1; i++) {
		float offset = _anchorLine.getDistances()[i];
		float segmentLength = _anchorLine.getDistances()[i+1]-_anchorLine.getDistances()[i];//_anchorLine.getPolars()[i].r;

		//  Fits?
		//
		if( segmentLength >= (m_label.width+_maxDistance) ){
			//  How many times?
			int nTimes = segmentLength/(m_label.width+_maxDistance);
            
			//  At what distance between each other?
			float margin = (segmentLength-m_label.width*(float)nTimes)/((float)nTimes+1.0);
            
			//  Add anchors points for seeds
			float seed = margin;
			for (int i = 0; i < nTimes; i++) {
				float potentialSeed = offset + seed ;
				if( potentialSeed-lastSeed > _minDistance ){
					lastSeed = potentialSeed;
					_anchorLine.marks.push_back(lastSeed);
					seed += m_label.width+margin;
				}
			}
		} else if ( segmentLength >= m_label.width+_minDistance){
			//  Only one time
			//
			float margin = (segmentLength-m_label.width)*0.5;
			float potentialSeed = offset + margin ;
			if( potentialSeed-lastSeed > _minDistance){
				lastSeed = potentialSeed;
				_anchorLine.marks.push_back(lastSeed);
			}
		}
	}

01

  • Fade according to tilt angle
	float angle = glm::dot(glm::normalize( *m_cameraPos - shapes[0].getCentroid()),glm::vec3(0.,0.,1.));
	m_alpha = lerpValue(m_alpha,powf( CLAMP(angle,0.01,1.0), 1.15 ),0.1);

02

  • Curved path following
	float angle = PI;
	glm::vec3 diff = _anchorLine[0]-_anchorLine[_anchorLine.size()-1];
	angle = atan2f(-diff.y, diff.x);
        
	if(angle < PI*0.5 && angle > -PI*0.5){
		for (int i = m_text.length()-1; i >=0 ; i--) {
			glm::vec3 src = _anchorLine.getPositionAt(_offset);
			if(screen.inside(src)){
				double rot = _anchorLine.getAngleAt(_offset);
				glPushMatrix();
				glTranslated(src.x, src.y, src.z);
				glScalef(1,-1,1);
				glRotated(rot*RAD_TO_DEG, 0, 0, -1);
				glScaled(-1, -1, 1);
				glTranslated(-m_lettersWidth[i], 0, 0);
				glTranslatef(0., -m_label.height*0.5,0.);
				m_font->drawString( std::string(1,m_text[i]), m_alpha );
				glPopMatrix();
				_offset += m_lettersWidth[i];
			} else {
				break;
			}
		}
	} else {
		for (int i = 0; i < m_text.length(); i++) {
			glm::vec3 src = _anchorLine.getPositionAt(_offset);
			if(screen.inside(src)){
				double rot = _anchorLine.getAngleAt(_offset);
				glPushMatrix();
				glTranslated(src.x, src.y, src.z);
				glScalef(1,-1,1);
				glRotated(rot*RAD_TO_DEG, 0, 0, -1);
				glTranslatef(0., -m_label.height*0.5,0.);
				m_font->drawString( std::string(1,m_text[i]), m_alpha );
				glPopMatrix();
				_offset += m_lettersWidth[i];
			} else {
				break;
			}
		}
	}

07

Point Labels

  • Project top points
	glm::ivec4 viewport;
	glm::mat4x4 mvmatrix, projmatrix;
	glGetIntegerv(GL_VIEWPORT, &viewport[0]);
	glGetFloatv(GL_MODELVIEW_MATRIX, &mvmatrix[0][0]);
	glGetFloatv(GL_PROJECTION_MATRIX, &projmatrix[0][0]);
	m_anchorPoint = glm::project(m_centroid+m_offset, mvmatrix, projmatrix, viewport);

03

  • Mutual occlusion using depth sort and bounding boxes
	bool depthSort(const glmFeatureLabelPointRef &_A, const glmFeatureLabelPointRef &_B){
		return _A->getAnchorPoint().z < _B->getAnchorPoint().z;
	}

	…

	std::sort(pointLabels.begin(),pointLabels.end(), depthSort);
	for (int i = 0; i < pointLabels.size(); i++) {
		if(pointLabels[i]->bVisible){
			for (int j = i-1; j >= 0 ; j--) {
				if (pointLabels[i]->isOver( pointLabels[j].get() ) ){
					pointLabels[i]->bVisible = false;
					break;
				}
			}
		}
	}

04

  • Occlude line labels with bounding box
	double rot = _anchorLine.getAngleAt(_offset);
	glmRectangle boundingBox = glmPolyline(m_label,angle).getBoundingBox();
	boundingBox.translate(_anchorLine.getPositionAt(_offset+m_label.width*0.5));

	bool bOver = false;
	for (int i = 0; i < pointLabels->size(); i++ ){
		if(pointLabels->at(i)->bVisible){
			if( boundingBox.intersects(pointLabels->at(i)->getLabel(0) ) ){
				bOver = true;
				break;
			}
		}
	}

06

  • Street level point of view 05

ofxvectortile's People

Contributors

karimnaaji avatar matteblair avatar patriciogonzalezvivo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ofxvectortile's Issues

EXC_BAD_ACCESS on app exit

Having the following crash when app exists. Any ideas?

EDIT - If I comment out that function, the crash stops. Is this needed for anything?

screen shot 2016-02-05 at 12 31 06 pm

Not working in openFrameworks 090

I'm trying to compile this on 090 on OSX 10.11, but i get a long list of errors. Starting with

clang: error: invalid deployment target for -stdlib=libc++ (requires OS X 10.7 or later)

Fixing this error (changing to libstd++) just opens up a new wormhole of errors.

examples won't run out of the box

I can create a new project, fix things up a bit and get the examples running on my machine eventually...
But had to fixed all these search paths myself.

screenshot 2014-11-17 15 23 41

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.