Mesh Spaces

dare
Data Mining the City
4 min readOct 20, 2017
Mesh Spaces Processing sketch

This project visualizes the geographies of New York City’s burgeoning cooperative internet network.

NYC Mesh is an internet cooperative that spans all five boroughs of New York City. A fascinating movement, its organizers aim to develop an alternative and free communications network not tied to any commercial internet service providers (ISPs). The subaltern internet network is formed through a web of wireless routers installed on buildings scattered in Brooklyn and Manhattan with a few nodes in Queens, the Bronx, Staten Island and Jersey City. Each router receives and conveys an internet connection within a certain range. The ad hoc project requires a certain kind of spatial logic — new nodes can only connect within a certain range of established nodes, each node needs an uninterrupted field of vision in order to be most effective — and makes use of particular kinds of spaces.

The spatial operations of NYC Mesh have parallels to Gordon Matta-Clark’s work in Fake Estates (1973–4). In that project Matta-Clark purchased fifteen tiny and irregularly shaped lots — “gutterspaces” — that were auctioned off by the city. He collected photographs, deeds and other forms of official bureaucratic information about these spaces. His slivers of land were own-able, subject to private property designations thus all of the associated ephemera and record keeping practices, and yet were largely unusable. NYC Mesh somewhat inverts this: perched on chimneys, balconies, rooftops the nodes put these marginal spaces to productive (re)use but without any claims of ownership to them.

Gordon Matta-Clark, Reality Properties: Fake Estates, Little Alley Block 2497, Lot 42, 1974 (posthumous assembly 1992), Image from Guggenheim Museum

Drawing inspiration from Matta-Clark the project creates a kind of information card for each node that collectively describe the geographies of this network and the spatial tactics at work. The card for each node is composed of: its visual field captured in a panoramic photograph, the strength of the network at the node represented by scaled transparent bar, the distance to the nearest node, and the name of the owner of the building where the node is cited.

The cards were generated through a multistep process: I scraped data available on the NYC Mesh website which identifies the locations of all of the nodes in the NYC Mesh network.

Locations and attribute information of existing nodes in the NYC Mesh network.

I then created a script to parse this messy json dataset and download panoramic photographs that have been taken by the NYC Mesh organizers for nearly all of the nodes. I measured the distances between the active nodes and identified the nearest nodes to each node using GIS.

Nodes in Brooklyn and Lower Manhattan with lines between the computed nearest nodes

Also using GIS, I combined the nodes dataset scraped from NYC Mesh with tax lot-level data available through MapPLUTO to identify the names of the building owners for the buildings where the nodes are cited. This new dataset was recomposed and then used to create the interactive drawing in Processing.

Nodes with underlying tax lots from MapPLUTO
import csvdef setup():
size(1450,850)
background(255)
stroke(0)
global f
f = createFont("Univers-Light",10, True)
global imageList
global distancevalue
global owner
imageList = []
distancevalue = []
owner = []
with open("data/Panos-active-distance-owner_manual.csv") as imgCsv:
csvReader = csv.reader(imgCsv)
for row in csvReader:
imageList.append(row[0])
distancevalue.append(int(float(row[2])))
owner.append(row[3])
print(owner)
global clickSequence
clickSequence = 0

global firstImage
global firstSignalStrength
global bldgOwner
bldgOwner = owner[clickSequence]
firstImage = loadImage(imageList[clickSequence])
firstSignalStrength = distancevalue[clickSequence]
def draw():
background(255)
#correctly sizing images
widthScale = firstImage.width/width
heightScale = ((firstImage.height)/widthScale)
#loading images
image(firstImage,0,(height-heightScale)/2,(firstImage.width)/widthScale,
(firstImage.height)/widthScale)
#bar for signal strength
noStroke()
fill(255, 0, 204,160)
rect(200,0,10000/firstSignalStrength,height)
# ellipse(width/4,height/2,imageSequence*40,imageSequence*40)
# ellipse(width/1.25,height/1.5,imageSequence*60,imageSequence*60)
# ellipse(width/1.5,height/3,imageSequence*30,imageSequence*30)

fill(255)
rect(0,height-70,width,height)
fill(0)
textFont(f)
text("Locations of Cooperatively Owned Internet Nodes",50, height-50)
text("Nearest node is {} feet away".format(firstSignalStrength),50,height-35)
text("This node is sited on a building owned by {}".format(bldgOwner),50,height-20)
textFont(f,30)
text("<",15,height-25)
text(">",width-40,height-25)
def mouseClicked():
global clickSequence
#global r
if mouseX > width/2:
clickSequence += 1
elif mouseX <width/2:
clickSequence -=1
print(clickSequence)
if clickSequence == len(imageList) or clickSequence == -len(imageList):
clickSequence = 0

global firstImage
firstImage = loadImage(imageList[clickSequence])

global firstSignalStrength
firstSignalStrength = 100000/distancevalue[clickSequence]

global bldgOwner
bldgOwner = owner[clickSequence]

--

--