Archive | Technology RSS feed for this section

A Street Bump Knockoff: Mobile Phone Acceleration

21 Jan

Some time ago, I read about an app that uses your phone to detect speed bumps. It sounded cool, but I didn’t give it much thought. Recently, I was asked a question about the app and took a harder look at it. The app is call Street Bump and is produced by the City of Boston. The app won a Best of the Web Government Achievement award in 2013 for the Government to Citizen category. The first thing that came to mind when reading about the app was could I build it. This article will walk you through how I built a very simple version of the Street Bump app.

My best guess was that the app used the z coordinate of the mobile device. I started reading about the HTML5 APIs that would be needed. As I read, I found that there is a DeviceMotion event that has an acceleration attribute. This is what I will use. Let’s think about it. You are driving down a road and the phone will move up and down. Hitting a pothole, your phone should change elevation quickly. The elevation change, however, will be minimal. Acceleration should be the right choice.

The Final App. A Chart Streaming Data and a Map With Pothole Locations

The Final App. A Chart Streaming Data and a Map With Pothole Locations

The first thing I wanted to do was read out the acceleration values.

window.addEventListener(“devicemotion”,function(e){
console.log(e.acceleration.z);},true);

Now I can see a bunch of numbers in the console. I want the mobile phone user to be able to see them too – there is no console on your phone. I decided to use Smoothie Charts to stream the data to the webpage.

The second part of the app is that the coordinates are sent to a server. To accomplish this, I used Leaflet.js map.locate(). It is just a wrapper around the HTML5 Geolocation API, but it lets me draw a map at the same time using a single API.

The final code

  1. Creates a map and a line for the chart.
  2. It draws a blank map, sets up the location events and functions and initializes the chart.
  3. The action occurs in the devicemotion event listener. When the event is fired, the code adds a time stamp and the z value to the chart and calls map.locate() to get the coordinates and draw a point.

Here is the full JavaScript for the app.

var raw=[];
var map = L.map(‘map’);
var line1 = new TimeSeries();

window.addEventListener(“devicemotion”,function(e){
line1.append(new Date().getTime(), e.acceleration.z);
console.log(e.acceleration.z);
raw.push(e.acceleration.z);
document.getElementById(“rawdata”).innerHTML=raw.join(“,”);
if(e.acceleration.z>3|e.acceleration.z<-3)
{map.locate({setView: true, maxZoom: 16});}},true);

var smoothie = new SmoothieChart({millisPerPixel:70,maxValueScale:0.82,grid:{fillStyle:’rgba(192,192,192,0.15)’,verticalSections:5},labels:{disabled:true,fillStyle:’#000000′,fontSize:12,precision:0},timestampFormatter:SmoothieChart.timeFormatter,maxValue:10,minValue:-10});
smoothie.addTimeSeries(line1, { lineWidth:5,strokeStyle:’#000000′});
smoothie.streamTo(document.getElementById(“mycanvas”), 1000);

function onLocationFound(e) {
L.tileLayer(‘http://{s}.tile.osm.org/{z}/{x}/{y}.png’).addTo(map);
L.marker(e.latlng).addTo(map);}

map.on(‘locationfound’, onLocationFound);

You can play with the if statement to change the values making the app more or less sensitive. The Street Bump algorithm is far more advanced than our simple if > 3 or < -3. Also, the Street Bump app sends the data to a server. If three people mark a pothole at the same location, the city will respond. Sending the data to a server would require an AJAX call or better yet, use WebSockets with a Node.js Server.

Ideally, the app is just a data collector sending a stream of acceleration values with (lat,long) for each to a database. The second part of the app is a program that analyzes the data finding multiple values that would signal a pothole. The more data collected, the smarter the app should become. For example, if a single line segment is recorded multiple times, the app should be able to average the values to account for different vehicle speeds, suspensions, etc. This can be feed back to the algorithm to make it smarter.

Revit REST API: Building as a Service

21 Jan

I have written a few posts on Revit and Databases: Revit DB Link pluginModifying Revit Data through the Web and  Linking a Revit DB to a QR Code.  I also wrote a post on the idea of downloading a building.  As I have been doing more coding, a mashup of these posts has finally hit me. I can download a building through the web and I can do it by creating a REST API on top of a Revit model exported to a database. This post will demonstrate a simple Building API using Revit.

The API

I am going to use a RESTish API. I use the -ish because there is no real specific for REST but rather guidelines. The way it works is you submit a get, post, delete or put request and get a JSON response. For this example I am going to hack together two endpoints: getWalls and editWalls. They will be located at http://localhost:8081/revitAPI/getWalls and http://localhost:8081/revitAPI/editWalls.

getWalls

When we hit the endpoint for getWalls, we want to have all the wall information returned as JSON. In this example, I will return the id and comments only. The page returns:

[{“id”:184159,”comments”:””},{“id”:184183,”comments”:””},{“id”:184205,”comments”:”Paul-NewestNewest-Comment”},{“id”:184237,”comments”:””},{“id”:184261,”comments”:””},{“id”:184290,”comments”:””},{“id”:184337,”comments”:”My Other Wall”},{“id”:184406,”comments”:”My Wall”},{“id”:184441,”comments”:””},{“id”:184476,”comments”:””},{“id”:999999,”comments”:”999999″}]

editWalls

editWalls takes two parameters: id and comment. Passing a valid wall id and a comment will result in the Revit Database being changed to reflect the new comment. If successful, the endpoint will return:

{“result”:{“status”:”Success”}}

Putting it Together

Now I have two RESTish endpoints. What do we do with them? Below is a simple webpage that edits and retrieves the wall table from Revit.

Capture

 

Clicking get walls returns a list of walls.

Wall Schedule. Notice the Badge Displays the Number of Results.

Wall Schedule. Notice the Badge Displays the Number of Results.

 

The edit walls menu allows you to put text in the box and it will return the wall schedule with the value of wall 184205 changed.

Paul Comment was added

Paul Comment was added

I can then open Revit and see the changes after loading the DBLink plugin.

Capture2

Thoughts

While this post seems similar to my post on modifying Revit data through the web, you are correct, but there is one fundamental difference – the model can now be queried. In my earlier posts, I only went one way- web to Revit. In this post, the model can talk to us and tell us what is in it – Revit to web. While I only displayed a table of results, you could query by height, area, sort, filter, or perform a whole host of operations on the results of the getWalls endpoint. Furthermore, you now have the ability to make the data public. Anyone could write a webpage analyzing your building data and if you do not allow edit capabilities, there is absolutely no risk to your model.

Note To Architects: If you designed a single front end to a Revit REST API, you would only need to change the urls to ship it to every client you have a BIM for. Write once, sell multiple times. As an architect, why stop making money when the building is complete? Why not get in on the facility management side and make money for the life of the building?

Making Money With BIM

29 Oct

Once in a while I will post something nontechnical- a rant if you will. Today is one of those in a whiles. My experience in architecture has led me to believe that architecture firms care only about construction drawings and the tools that are immediately required to produce said drawings. That is being a bit harsh, they might throw in a render here or there. Research and development are nonexistent as is exploring new technology. Maybe I should restate my previous claim that architects care only about CDs and say that: If it ain’t billable, it ain’t doable. Architects also seem interested in selling their design services only. The economic downturn should have taught them that they possess more than design skills and there is money to be made in other areas – but I fear it did not. Let’s explore making money with BIM in light of these observations about architecture firms.

BIM is expensive – if you buy Revit – and has a learning curve. Training doesn’t come cheap and lots of firms want to hire a BIM specialist to train everyone to keep costs down. This just results in slower learning and inefficiencies in projects. Firms tend not to give the model away and can’t command higher commissions because they use BIM. The client only wants the CDs anyway so why would they pay extra for anything else? If all this is true, how do we make money with BIM?

The usual way to justify BIM is that you will save money by decreasing the number of change orders or competing your project faster. This is the old sell my design skills thinking. Why not leverage the model to sell additional services on the back end.

Architectural data a a service.

The architect has a model that can be updated throughout the lifecycle of the building. Repairs and maintenance on the building can be updated in the model and given back to the client. The BIM can be sold as a subscription based software package for facility management through a web based front end. The client doesn’t need, nor do they often want, the BIM in some proprietary format like .RVT. They want a schedule and maybe an image showing where something is. This makes the task even easier. 90% of a clients needs will be updated properties of the building – not changes to the geometry. Simplifying the job even further. Data is valuable. Data is worth $$. The architect holds more data about a building than the owner. Multiplied by the number of buildings the firm has built.

Why let a client go when a building is done? Architects need to expand their services. Architects hold data that is vital in operating the building for decades to come. The data was created and paid for during the design of the building. Any money made off of it after design is profit. How easy with all the tools available today to stand out and find additional revenue streams based off work that is already being done. It could be something as simple as handing over an HTML version of an owners manual – not a pdf. Or if a pdf, at least embed hyperlinks or other interactive features.

The future of architecture is data. Those that have it and can use it will win. Design is important, and always will be, but the services you can provide above and beyond that is where value resides for you and the client.

This concludes my rant. It is lacking in detail but it is my preliminary thoughts on the issue. The ideas need to be flushed out and elaborated on but the meat is there.

Revit and RabbitMQ: Passing Data in to Revit from Outside Applications

25 Oct

UPDATED:

I threw together a quick website using CherryPY to pass data to Revit. The QR Code pictured below, when scanned, will pull up the website, triggering the data in it to be sent to Revit. Picture a QR Code with info on a HVAC Unit, you scan it and the data is passed to Revit for when it was installed or serviced.

Sending Data in a URL to Revit. Data can be parsed to up date parameters of object.

Sending Data in a URL to Revit. Data can be parsed to update parameters of object.

QR Code with embedded data to send to Revit.

QR Code with embedded data to send to Revit.

 

 

 

 

 

 

 

 

 

 

***************************************************************************

ORIGINAL:

 

Modifying Revit from outside the program has been my primary interest for some time.

Initially, I was fascinated by the Revit DBLink plugin and wrote a few proof of concepts that relied on the following architecture:

Revit <—–> Database<—–>Outside Program

I have recently posted proof of concepts about sending data in to Revit from outside – skipping the database export– but used GIS as my example, arguing that because GIS and Revit use the same API language it should be possible.

I now have a working example in Revit. The architecture no longer requires a Revit DB to be exported.

Revit <——- RabbitMQ<———-Outside Program. (can be bidirectional if want it to)

I wrote a Revit Add-In that connects to a Messaging Queue and retrieves any waiting messages. Getting the message in to Revit is the hard part. Once in, we can use it to modify properties – like in the GIS example that drew points from a message.

The screenshots show the Add-In, No Messages Waiting, and a Message Coming In.

This is my proof of concept and the goal is to modify this program to allow the scanning of a QR code to send a message in to Revit and modify/add properties to an object. That architects looks like this:

Revit<—— RabbitMQ<——-WebServer <——- QR Code scanned by mobile device

The Qr Code Opens a URL with Parameters(http://somewhere.com/revit?id=123&wallheight=12

The WebServer is a CherryPy Script that reads in the parameters and passes them as a message to RabbitMQ using Pika.

The Revit Add-In gets the message and modifies the properties of the wall with ID=123

John Keats Poems in 1820: Graphing Words Used with NetworkX and Python

14 Dec
Nodes Weighted by Number of Times They Appear in Keats 1820 Poems.

Nodes Weighted by Number of Times They Appear in Keats 1820 Poems.

You should have watched the NetworkX and Gephi talk from PyData NYC 2012 by Gilad Lotan by now. This is my second example of NetworkX inspired by his talk. This example reads through John Keats poems from 1820 and using a portion of Gilad’s add_node(): I create a node for each word used and a weight. Then I brought it in to Gelphi to make it pretty.I took out any word that occured less than 10x – otherwise ‘the’ and ‘and’ are the tops words. Not exciting. I’m looking for rhyming and interesting words. Here is the code.

import networkx as nx
import matplotlib.pyplot as plt
from collections import Counter
import re

words= re.findall(‘\w+’,open(‘keats1820.txt’).read().lower())

g=nx.Graph()

def add_node(n,weight=None):
if not g.has_node(n):
g.add_node(n)
g.node[n][‘weight’] = weight

occur=Counter(words)

for x in Counter(words):
add_node(x,occur[x])

nx.draw(g)
nx.write_gexf(g, “keats1820.gexf”)

Social Network in Python Using NetworkX

14 Dec
My First Network Graph using NetworkX and Gephi.

My First Network Graph using NetworkX and Gephi.

I recently stumbled upon the PyData NYC 2012 Channel on Vimeo. This in turn led me to a talk by Gilad Lotan on NetworkX and Gephi. His talk is awesome, please check it out. I have played with NetworkX a little, mostly for a demonstration on Python and mapping I gave, so it was just an overview and I didn’t get to spend much time on it. After watching Gilad’s talk, I thought I would revisit NetworkX. I want to show a simple example of how to create a graph using NetworkX. I will save it as a PNG and a .GEXF to be edited in Gephi.

I hard coded a series of Nodes and Edges in my Python code. The nodes are the Names of people in the circles on the above image. The edges are the lines between them. I then used matplotlib to show the graph and to save it out as a .gexf. Here is the code:

import networkx as nx
import matplotlib.pyplot as plt

g=nx.Graph()

g.add_node(“Paul”)
g.add_node(“Joe”)
g.add_node(“Bill”)
g.add_node(“John”)
g.add_node(“Sarah”)
g.add_node(“Mary”)
g.add_node(“Karen”)
g.add_node(“Betsy”)
g.add_edge(“Betsy”,”Karen”)
g.add_edge(“Betsy”,”Paul”)
g.add_edge(“Betsy”,”Sarah”)
g.add_edge(“Paul”,”Sarah”)
g.add_edge(“Karen”,”Sarah”)
g.add_edge(“Sarah”,”Mary”)
g.add_edge(“Paul”,”Mary”)
g.add_edge(“Bill”,”Mary”)
g.add_edge(“John”,”Mary”)

nx.draw(g)
plt.savefig(“Something.png”)
nx.write_gexf(g, “Something.gexf”)

Import the libraries, create a graph, add nodes, add edges, then save. Simple. Now you can pull it in to Gephi and make it pretty- since this is the output I got from Matplot:

Output from Matplotlib - plt.show()

Output from Matplotlib – plt.show()


I won’t go in to detail on how to use Gephi – because honesty, I just used it for the first time – watch Gilad’s talk and learn from him – he knows what he’s doing!

Albuquerque Public Art

10 Dec

Albuquerque has released a bunch of data as part of their transparency initiative. The best of the data is in KML, which I am not thrilled about. Wish that open initiatives would use formats like CSV or JSON instead of SHP and KML.

Oh well, I have moved on. Their public art file is cool. It is a KML of points where you can find art in ABQ with a table of information and an image. I scrubbed the KML through some python scripts I wrote and got the Long, Lat, and a URL to an image. Let me add, they have a website with this map already, but it is an embedded ArcGIS Online map.   I am giving away the data in a python script that creates a MongoDB with geospatial indexing enabled(GEO2D).

The code is a lot of insert statements:

from pymongo import Connection
from pymongo import GEO2D

db=Connection().albuquerque
#db.drop_collection(“publicart”) you shouldn’t need this.
db.publicart.create_index([(“loc”,GEO2D)])

db.publicart.insert({“loc”:[35.1555,-106.591838],”name”:”Almond Blossom/Astronomy”,”popup”:”http://farm8.staticflickr.com/7153/6831137393_fa38634fd7_m.jpg&#8221;})
db.publicart.insert({“loc”:[35.0931,-106.664177],”name”:”Formas Esperando Palabra de Otros Mundos”,”popup”:”http://farm3.staticflickr.com/2167/2479129916_0d861b2600.jpg&#8221;})
db.publicart.insert({“loc”:[35.1143,-106.577991],”name”:”Sumer #24″,”popup”:”http://farm2.staticflickr.com/1416/908720823_e390a242f4.jpg&#8221;})
db.publicart.insert({“loc”:[35.0682,-106.570886],”name”:”Images”,”popup”:”http://farm8.staticflickr.com/7012/6831253349_52c0a680ba.jpg&#8221;})
……….

The full python file is on my website.