home products news downloads documentation support gallery online maps resellers search
TNTmips Downloads Menu

HOME

CONTACT US

CURRENT RELEASE
  TNT 2013

DEVELOPMENT VERSION
  TNT 2014

TNTmips Pro
PRIOR RELEASES
  TNT 2012

FREE SOFTWARE
  TNTmips Free
  TNTatlas
  TNTsdk

MORE DOWNLOADS
  HASP Key Driver
  Screen Recorder
  TNT Language Kits
  Sample Geodata
  TNT Scripts

DOCUMENTATION
  TNTmips Tutorials
  Tutorial Datasets
  Technical Guides
  Scripts
  Quick Guides

MORE INFO
  Download FAQs
  FTP
  Download Managers
  Find Reseller

SITE MAP


schools.sml


#LincolnSchools Demonstration Control Script.
#
#Requirements:
# - TNTmips 7.0 (or later)
# - LincolnSchools layout
# - Lincoln Property Viewer Atlas DVD
#
#This script can only be run as a control script.  To use this script, open the LincolnSchools 
#layout.  In the Layout Controls of Spatial Data Display, click Layout / Edit Control Script.

numeric schoolPrclScl = 50000;
numeric mouselocPrclScl = 15000;
numeric labelOffset = 30;
numeric schoolSymOffset = 25;
class GEOREF vecGeoref;
class POINT2D offset;

#FindPointInPoly
#
#pre:
#takes mouse location in map coordinates.
#vPoints and vPolys assumed to have same georef and be in same projection as point.
#
#post:
#returns 1 if point found in poly and places point in pointloc
#returns 0 if point not found in poly, and pointloc is unmodified.

func FindPointInPoly(
	class POINT2D pointloc, 
	class VECTOR vPoints, 
	class VECTOR vPolys, 
	class POINT2D cursorpos) 
{
	numeric closepoly = FindClosestPoly(vPolys, cursorpos.x, cursorpos.y);
	numeric i;
	for(i=1; i<=vPoints.$info.NumPoints; i++) {
		numeric polyForPoint = FindClosestPoly(vPolys, vPoints.Point[i].Internal.x, vPoints.Point[i].Internal.y);
		if(polyForPoint == closepoly) {
			pointloc.x = vPoints.Point[i].Internal.x;
			pointloc.y = vPoints.Point[i].Internal.y;
			return 1;
		}
	}
	return 0;
}

func FindPointInPolyElemNum(
	class VECTOR vPoints,
	class VECTOR vPolys,
	class POINT2D cursorpos) 
{
	numeric closepoly = FindClosestPoly(vPolys, cursorpos.x, cursorpos.y);
	numeric i;
	for(i=1; i r.x2) opcode = opcode | 2;
	if(p.y > r.y2) opcode = opcode | 4;
	if(p.y < r.y1) opcode = opcode | 8;
	return opcode;
}

#clipPoint
#
#For point a outside the view window, finds the intersection of the view
#window's extents with the line from the mouse pointer location to a.
#For a point inside the view window, returns the point location.
#
#pre: all input parameters are in screen coordinates.  ext is the view window's
#extents in screen coordinates
#
#post: returned POINT2D is the location on the edge of the extents of
#the view window (or just the location of the point if already inside the view).

func class POINT2D clipPoint(class POINT2D p, class POINT2D mouseloc, class RECT ext) {
	class POINT2D out = p;
	numeric outcode = getBinaryOutcode(out, ext);
	while(outcode != 0) {
		class POINT2D temp = out;
		if(outcode & 1 == 1) {
			#clip left
			temp.x = ext.x1;
			temp.y = mouseloc.y + getTriOppositeLength(mouseloc.x - out.x, mouseloc.y - out.y, ext.x1 - mouseloc.x);
		} else if(outcode & 2 == 2) {
			#clip right
			temp.x = ext.x2;
			temp.y = mouseloc.y + getTriOppositeLength(mouseloc.x - out.x, mouseloc.y - out.y, ext.x2 - mouseloc.x);
		}	else if(outcode & 4 == 4) {
			#clip bottom
			temp.x = mouseloc.x + getTriOppositeLength(mouseloc.y - out.y, mouseloc.x - out.x, ext.y2 - mouseloc.y);
			temp.y = ext.y2;
		} else if(outcode & 8 == 8) {
			#clip top
			temp.x = mouseloc.x + getTriOppositeLength(mouseloc.y - out.y, mouseloc.x - out.x, ext.y1 - mouseloc.y);
			temp.y = ext.y1;
		}
		out = temp;
		outcode = getBinaryOutcode(out, ext);
	}
	return out;
}

func calcAngle(class POINT2D a, class POINT2D b) {
	numeric x = b.x - a.x;
	numeric y = b.y - a.y;
	numeric angle = acos(x / sqrt(x^2 + y^2));
	if(y < 0) return PI - angle;
	return angle - PI;
}

proc drawAngledLine(class GC gc, numeric x, numeric y, numeric angle, numeric len) {
	numeric a = len * cos(angle);
	numeric b = len * sin(angle);
	gc.MoveTo(x, y);
	gc.DrawTo(x-a, y-b);
}

proc drawAngledPoint(class GC gc, numeric x, numeric y, numeric angle, numeric len) {
	numeric a = len * cos(angle);
	numeric b = len * sin(angle);
	gc.DrawPoint(x-a, y-b);
}

func class POINT2D getAngledPoint(numeric x, numeric y, numeric angle, numeric len) {
	class POINT2D pt;
	pt.x = x - len * cos(angle);
	pt.y = y - len * sin(angle);
	return pt;
}

#drawParcel

#draw a parcel polygon and returns its extents.
#
#pre: tp is the transparm from layer to screen, and parcelPolyID is the polygon number of the
#parcel to draw.

func class RECT drawParcel(
	class GC gc, 
	class TRANSPARM tp, 
	class VECTOR parcelVec, 
	numeric parcelPolyID) 
{
	array polyLines[2048]; #arbitrarily large-sized array
	numeric numPolyLines = GetVectorPolyLineList(parcelVec, polyLines, parcelPolyID);
	numeric i;
	class RECT parcelExtents;
	for(i = 1; i <= numPolyLines; i++) {
		class POLYLINE curLine = GetVectorLine(parcelVec, polyLines[i]);
		curLine.ConvertForward(tp);
		parcelExtents.ExtendRect(curLine.ComputeExtents());
		gc.DrawPolyLine2(curLine);
	}
	return parcelExtents;
}

# Function called when the cursor pauses triggering a datatip action event
func OnViewDataTipShowRequest(class GRE_VIEW view, class POINT2D mouseScrn, class TOOLTIP datatip)
{
	view.RestoreAll();
	class GC gc = CreateGCForDrawingArea(view.DrawingArea);
	ActivateGC(gc);
	gc.SetColor("white");
	class STRING name = "Schools";
	class GRE_LAYER_VECTOR curPtLayer = MainLayout.GetGroupByName("Schools").FirstLayer;
	class GRE_LAYER_VECTOR curDistLayer = MainLayout.GetGroupByName("School Districts").FirstLayer;
	class GRE_LAYER_VECTOR parcels = MainLayout.GetGroupByName("Overlays").GetLayerByName("Parcels");
	class VECTOR parcelVec;
	VectorLayerGetObject(parcels, parcelVec);
	class TRANSPARM tpPrclToScrn = ViewGetTransLayerToScreen(view, parcels);
	class POINT2D mousepoint;
	#draw parcel underneath mouse pointer
	mousepoint = TransPoint2D(mouseScrn, ViewGetTransViewToScreen(view, 1));
	mousepoint = TransPoint2D(mousepoint, ViewGetTransMapToView(view, parcels.Projection, 1));
	numeric closeParcel = FindClosestPoly(parcelVec, mousepoint.x, mousepoint.y);
	if(closeParcel != 0 && view.CurrentMapScale < mouselocPrclScl) {
		gc.SetLineWidth(2);
		class RECT parcelExtents = drawParcel(
			gc, 
			tpPrclToScrn,
			parcelVec,
			closeParcel);
		class string parcelAddress = parcelVec.Poly[closeParcel].CA032904.SITUS_ADDR$;
		gc.DrawTextSetHeightPixels(12);
		numeric addressLen = gc.TextGetWidth(parcelAddress);
		gc.SetColor("Lemon Chiffon");
		gc.FillRect(parcelExtents.x2 + 10, parcelExtents.y2, addressLen, 12);
		gc.DrawTextSetFont("Arial");
		gc.DrawTextSimple(parcelAddress, parcelExtents.x2 + 10, parcelExtents.y2 + 11);
	}
	#draw school locations and parcels
	class STRINGLIST parcelColors;
	numeric iterNum=1;
	for(iterNum = 1; curPtLayer != 0 && curDistLayer != 0; iterNum++) {
		class VECTOR ptsVect, distVect;
		VectorLayerGetObject(curPtLayer, ptsVect);
		VectorLayerGetObject(curDistLayer, distVect);
		class string styleObj = "STYLE";
		gc.DrawUseStyleSubObject(_context.Filename, ptsVect.$info.Name, styleObj);
		class POINT2D schoolLoc, mousepoint;
		numeric pointElemNum;
		mousepoint = TransPoint2D(mouseScrn, ViewGetTransViewToScreen(view, 1));
		mousepoint = TransPoint2D(mousepoint, ViewGetTransMapToView(view, curDistLayer.Projection, 1));
		if((pointElemNum = FindPointInPolyElemNum(ptsVect, distVect, mousepoint)) != -1) {
			schoolLoc.x = ptsVect.Point[pointElemNum].Internal.x;
			schoolLoc.y = ptsVect.Point[pointElemNum].Internal.y;
			schoolLoc = TransPoint2D(schoolLoc, ViewGetTransMapToView(view, curDistLayer.Projection));
			schoolLoc = TransPoint2D(schoolLoc, ViewGetTransViewToScreen(view));
			class RECT extents;
			numeric buf=5;
			extents.x1 = buf; extents.y1 = buf; extents.x2 = view.width-buf; extents.y2 = view.height-buf;
			class POINT2D newLocation = clipPoint(schoolLoc, mouseScrn, extents);
			class TEXTSTYLE textStyle;
			textStyle.Shadow = 1;
			gc.TextStyle = textStyle;
			gc.DrawTextSetColors("white", "black");
			gc.DrawTextSetFont("Arial Black");
			gc.DrawTextSetHeightPixels(12);
			class string schoolName = ptsVect.Point[pointElemNum].SchoolName.Name$;
			schoolName = schoolName.toUppercase();
			numeric textWidth = gc.TextGetWidth(schoolName);
			gc.DrawSetPointStyle("School");
			if(newLocation.x != schoolLoc.x || newLocation.y != schoolLoc.y) {
				gc.SetColor("white");
				numeric angle = calcAngle(schoolLoc, mouseScrn);
				gc.DrawArrow(newLocation.x, newLocation.y, angle * 180 / PI, 20, 20);
				gc.SetLineWidth(3);
				drawAngledLine(gc, newLocation.x, newLocation.y, angle, 40);
				gc.SetLineWidth(1);
				drawAngledPoint(gc, newLocation.x, newLocation.y, angle, 70);
				class POINT2D textpos = getAngledPoint(newLocation.x, newLocation.y, angle, 70);
				gc.DrawTextSimple(schoolName, textpos.x - textWidth/2, textpos.y + labelOffset);
			} else {
				if(view.CurrentMapScale < schoolPrclScl) {
					class POINT2D schoolLocParcel = TransPoint2D(schoolLoc, ViewGetTransViewToScreen(view, 1));
					schoolLocParcel = TransPoint2D(schoolLocParcel, ViewGetTransMapToView(view, parcels.Projection, 1));
					numeric schoolPolyID = FindClosestPoly(parcelVec, schoolLocParcel.x, schoolLocParcel.y);
					gc.DrawSetLineStyle("Parcel");
					class RECT parcelExtents = drawParcel(gc, tpPrclToScrn, parcelVec, schoolPolyID);
					class POINT2D screenCenter;
					screenCenter.x = view.Width/2;
					screenCenter.y = view.Height/2;
					numeric yPointPos = parcelExtents.y2 + schoolSymOffset;
					#gc.DrawSetPointStyle("School");
					gc.DrawPoint(newLocation.x, yPointPos);
					gc.DrawTextSimple(schoolName, newLocation.x - textWidth/2, yPointPos + labelOffset);
				} else {
					gc.DrawPoint(newLocation.x, newLocation.y);
					gc.DrawTextSimple(schoolName, newLocation.x - textWidth / 2, newLocation.y + labelOffset);
				}
			}
		}
		curPtLayer = curPtLayer.NextLayer;
		curDistLayer = curDistLayer.NextLayer;
	}
	return 1;
}


Back Home ©MicroImages, Inc. 2013 Published in the United States of America
11th Floor - Sharp Tower, 206 South 13th Street, Lincoln NE 68508-2010   USA
Business & Sales: (402)477-9554  Support: (402)477-9562  Fax: (402)477-9559
Business info@microimages.com  Support support@microimages.com  Web webmaster@microimages.com

25 March 2009

page update: 26 May 11