Archive | October, 2012

Interactive AutoCAD in Website

31 Oct

I have previously shown how to put a drawing in a website using DWF and OpenLayers. This time I will show how to use an image map created by Qgis.

Save your drawing as a DXF. I am interested in room polygons so here is my drawing:

Bring this drawing in to Qgis as a polygon using the dxf2shp converter plugin.

You now have a shapefile:

Open the editor and add a column for room names. I also added a column for URLs which will be used for a popup later.

Now we can export the drawing to an image map based website using the HTML Image Map Plugin.

Configure the webpage using the options provided. I am using the URL field for “href attr” option. This will make it a link that can be clicked. I will ignore the onlclick, and stick with a hover.

 

 

 

I opened up the HTML code and added a title, my face, and put the hover <DIV> at the bottom of the page. When you hover over a room, you will see the type of room displayed on the bottom of the page and as a tooltip. If you click a room, you will be taken to a website. You can fully customize this website. And I suggest you do.

Here are all my files in a ZIP if you want to play with the webpage or see my awesome DXF. The File is named “Files.DOC” I had to do this to upload them. Rename the file to “Files.ZIP” and it will work fine. FYI – this is a cool trick to hide files. Windows reads the extension and makes it look like the extension. But it is really whatever you created originally.

Advertisements

Shapefiles to AutoCAD DWG Using Python

29 Oct

This will be my last post on this topic. I will show how to create a DWG from a shapefile using python. This requires AutoCAD – as my other methods did not.  You will also need python, shapefile.py and pyautocad – and it’s dependency.

With AutoCAD open I run this code:

from pyautocad import Autocad, APoint
import shapefile

openshape = shapefile.Reader(“C:\Documents and Settings\user\Desktop\surveyShapefile”)
shpPoints = openshape.shapes()

acad = Autocad()

def readShapefile():
x = 0
while (x <= 100):
xy= shpPoints[x].points[0]
p1 = APoint(xy[0], xy[1])
acad.model.AddCircle(p1, .0001)
print ‘Reading Record: ‘+ str(x)
x=x+1

else:
print ‘Complete…’

readShapefile()

The result is my Survey in AutoCAD as points with the correct coordinates – coordinates from the GIS  in this case are WGS84.

We can modify the script by adding: acad.model.AddLine(p1, p2). This will convert a line shapefile to autoCAD. The code:

from pyautocad import Autocad, APoint
import shapefile

openshape = shapefile.Reader(“C:\Documents and Settings\user\Desktop\majorstreets”)
shpPoints = openshape.shapes()

acad = Autocad()

def readShapefile():
x = 0
while (x <= 5):
xy1 = shpPoints[x].points[0]
p1 = APoint(xy1[0], xy1[1])
xy2 = shpPoints[x].points[1]
p2= APoint(xy2[0], xy2[1])
acad.model.AddLine(p1, p2)
print ‘Reading Record: ‘+ str(x)
x=x+1

else:
print ‘Complete…’

readShapefile()

 

And the results:

 

You can use AutoLISP or probably .NET but Python is free and easy to learn.  Well, now you know another way to load shapefiles in to AutoCAD. With this in CAD, you can save it as a DWG and go straight to Revit.

And it does 3D:

from pyautocad import Autocad, APoint
acad = Autocad()

p1= APoint(10,10,10)
acad.model.AddCircle(p1, 10)

Let me state again that this code is sloppy – but functional. It is for demonstration purposes, so if you use it, clean it up and make the loops better.

Shapefiles to Revit or AutoCAD: Using Python to write DXF

29 Oct

I have shown how to get shapefiles in Revit Using Qgis, and mentioned how to do the same with AutoDesk Civil and ESRI ArcMap. But I have another way – Python.

I have written a program that will read in a point shapefile and convert it to DXF. If you have a survey point shapefile, run my script and you will have a survey point DXF. I would love to write to DWG but AutoDesk charges for that library – proprietary file formats and all….

I always start my programs with baby steps – no matter how simple the problem. So let me walk through how this code developed.

First, I drew a DXF from Python manually – lines then points.

Lines:

from dxfwrite import DXFEngine as dxf
drawing = dxf.drawing(‘testLines.dxf’)
drawing.add_layer(‘SURVEY’)
drawing.add(dxf.line((0, 0), (1, 0), color=7, layer=’SURVEY’))
drawing.add(dxf.line((2, 0), (3, 0), color=5, layer=’SURVEY’))
drawing.save()

Points:

from dxfwrite import DXFEngine as dxf
drawing = dxf.drawing(‘DXF.dxf’)
drawing.add_layer(‘SURVEY’)
points = dxf.point((1, 5), color=7, layer=’SURVEY’)

drawing.add(points)

drawing.save()

Then I wanted to try from an Excel file since this is easy practice for passing points to the DXFEngine:

from dxfwrite import DXFEngine as dxf
import xlrd
book = xlrd.open_workbook(“readdxf.xls”)
sh = book.sheet_by_index(0)
drawing = dxf.drawing(‘DXFFromExcel.dxf’)
drawing.add_layer(‘SURVEY’)

def readRow():
for rownum in range(sh.nrows):
rows=sh.row_values(rownum)
points = dxf.point((sh.cell_value(rowx=rownum, colx=0), sh.cell_value(rowx=rownum, colx=1)), color=7, layer=’SURVEY’)
drawing.add(points)
print ‘Reading Record: ‘+ str(rownum)

else:
print ‘Complete…’

readRow()
drawing.save()

Lastly, I read from a shapefile:

from dxfwrite import DXFEngine as dxf
import shapefile
drawing = dxf.drawing(‘DXFFromSHP.dxf’)
drawing.add_layer(‘SURVEY’)
openshape = shapefile.Reader(“C:\Documents and Settings\user\Desktop\surveyShapefile”)
shpPoints = openshape.shapes()

def readShapefile():
x = 0
while (x <= 100):
points = dxf.point((shpPoints[x].points[0]), color=7, layer=’SURVEY’)
drawing.add(points)
print ‘Reading Record: ‘+ str(x)
x=x+1

else:
print ‘Complete…’

readShapefile()
drawing.save()

The loop is lame and only grabs the first 100 points. I just wanted to quickly show how to do it. Modify this anyway you want – you will need to add your file names anyway.

This file can also be modified to read and write polyline shapefiles too.

You will need to install Python, shapefile.py and DXFwrite.py for this to work. I have tested the DXF files in Qgis, but not in AutoCAD or Revit.

Shapefiles in Revit: Method II

25 Oct

Need to get shapefiles from your GIS in to Revit? I will tell you how using open source software. But first, Revit does not like coverages of over 20 miles so you may need to crop your shapefile.

Download Qgis – a free and open source GIS.

Open your shapefile in Qgis.

It will appear in the table of contents on the left. Right click on it and select ‘Save as..’ Choose AutoCAD DXF.

You now have a DXF of your shapefile.

Want to bring AutoCAD – or Revit – to GIS? Do everything in Reverse. But first activate your plugins.

Go to ‘Plugins’ and ‘Manage Plugins’. Check DXF2SHP.

Now click DXF2SHP and select your DXF. Choose a name and location to save your shapefile. Select the type. Probably polyline.

Here is a DXF loaded

Now your CAD drawing can be used in a GIS.

Python, Point Shapefile and Qgis: Part II

24 Oct

In my first post, I showed how to create a shapefile from an excel sheet – but it was hard coded by cell. Not very useful.  Here is the code to loop through the sheet and create shapefile, then send a text telling me the job finished. The last thing to do is render the shapefile – Mapnik would work for this.
Here is the code:

import shapefile
import xlrd
import smtplib
book = xlrd.open_workbook(“NAME OF XLS FILE.XLS”)
sh = book.sheet_by_index(0)
w = shapefile.Writer(shapefile.POINT)
w.field(‘Type’)
w.field(‘Address’,’C’,’40’)

def readRow():

for rownum in range(sh.nrows):
rows=sh.row_values(rownum)
w.point(sh.cell_value(rowx=rownum, colx=0), sh.cell_value(rowx=rownum, colx=1))
w.record(sh.cell_value(rowx=rownum, colx=2),sh.cell_value(rowx=rownum, colx=3))
print ‘Reading Record: ‘+ str(rownum)

else:
print ‘Complete…’

readRow()

w.save(‘shapenull’)
message = ‘Job Complete’
server = smtplib.SMTP( ‘smtp.gmail.com’, 587 )
server.starttls()
server.login( ‘YOUREMAIL@gmail.com’, YOUR PASSWD’ )
server.sendmail( ‘YOUR PHONE #@mms.att.net’, ‘TO PHONE #@mms.att.net’, message )

The code opens the excel file formatted as: Lat, Long, Type, Address. Creates a point shapfile with fields for type and address.  Create a function that loops through the excel sheet. The Long, Lat, Type and Address are always in the same column so we only need to replace the row number of our cell and we do that by using the rownum variable in the loop.

While running, it will print out the current rownumber then print Complete.. when done. Lastly, It will send a text message saying that it has finished.

Simple.  Less than 25 lines of code. Set this to run as a task in Windows or as a Cron Job.

Python, Point Shapefile and Qgis

23 Oct

I have been getting data in a CSV and bringing it to Qgis using ‘Import Delimited Text.’  I could probably write a Python script in Qgis to do this automatically, but I only recently started reading the Qgis Python Cookbook. I have some experience with a Python Library for shapefiles already, so I will show how to create a point shapefile using this library.

Download Shapefile.py. All my maps are in WGS84, making this very easy. Open Notepad or your IDE and write the following:

import shapefile
w = shapefile.Writer(shapefile.POINT)
w.point(-106.505325, 35.069018)
w.point(-106.509378, 35.067741)
w.point(-106.527414, 35.108816)
w.field(‘type’)
w.field(‘street’)
w.record(‘res burg’,’central’)
w.record(‘auto burg’,’menaul’)
w.record(‘auto theft’,’eubank’)
w.save(‘point’)

I have three points in Albuquerque, with two fields: type and street. Running this file will create a shapfile without a PRJ. That’s alright, open the shapefile in Qgis. You should be asked for the projection. Choose WGS 84. It will display correctly. Now the points are on the map.

Right click on the shapefile in the table of contents and save as… Make sure the CRS is set to WGS 84.

Now when you open the shapefile you will not need to specify a projection.

Simple, right? Well, I hate hard coding the coordinates. I want to read from a file and everyone seems to send me data in Excel files so I downloaded XLRD and XLWT to read and write Excel files.

Here is how to add two points from an Excel Spreadsheet – you will want to run this as a loop to load all the data instead of hard coding it again. I will leave that up to you. (UPDATE: I can’t leave you hanging. Here is a new post with the code for looping). Here is the code to read the Excel file and write the shapefile.

book = xlrd.open_workbook(“test.xls”)
sh = book.sheet_by_index(0)
w = shapefile.Writer(shapefile.POINT)
w.point(sh.cell_value(rowx=0, colx=0), sh.cell_value(rowx=0, colx=1))
w.point(sh.cell_value(rowx=1, colx=0), sh.cell_value(rowx=1, colx=1))
w.field(‘type’)
w.field(‘street”)
w.record(sh.cell_value(rowx=0, colx=2),sh.cell_value(rowx=0, colx=3))
w.record(sh.cell_value(rowx=1, colx=2),sh.cell_value(rowx=1, colx=3))
w.save(‘fromExcel’)

Is this any easier than importing a CSV and creating the shapefile? No. But what it lets me do is schedule the Python file to run at intervals and update the shapefile even if I am at home sleeping. When graveyard shift comes in, they can see the latest data without me having to create it. It also allows me to add other functionality and python scripts.

I can filter the CSV by type or by location for example. Better yet, when a point in the shapefile exceeds some value, I can send a text to my phone – like this:

import shapefile
import xlrd
import smtplib
book = xlrd.open_workbook(“realtime.xls”)
sh = book.sheet_by_index(0)
w.record(sh.cell_value(rowx=1, colx=2))
w.save(‘writeANDreadANDshapefile’)

x = sh.cell_value(rowx=1, colx=2)
if x > 100:
message = “At Point: “+ str(sh.cell_value(rowx=1, colx=0)) +”,” + str(sh.cell_value(rowx=1, colx=1)) +”Levels equal: “+str(sh.cell_value(rowx=1, colx=2))
server = smtplib.SMTP( “smtp.gmail.com”, 587 )
server.starttls()
server.login( ‘YourAccount@gmail.com’, ‘Your Password’ )
server.sendmail( ‘From Phone Number@mms.att.net’, ‘ToPhoneNumber@mms.att.net’, message )

else:
print ‘Levels are normal’

All the concatenation of Message =”….” will create a string that says: “At Point (-106.4567, 35.3445) Levels Equal: 125” but will fill in the numbers using the actual coordinates and value.

There are programs – like CrimeView – that do this sort of thing automatically. But the way I showed was free and can be modified as you wish. Trying modifying the code of a proprietary software solution….Good Luck and Happy Hacking.

Crystal Reports for Revit Schedules

1 Oct

I have been playing with Crystal Reports and think they are an excellent option for Revit schedules.  With Cystal Reports you can design and write a single report to work on EVERY Revit project. The report handles all the data collection and adjusts itself to fit the data.

I have a fake room schedule in Excel (I exported the schedule and imported to Excel). Opening Crystal Reports, I select a new connection and choose Access. Under Access is the option for Excel 8.

When I select the Excel file, I can choose the sheets. Choose sheet 1.

Now I have a designer screen in Crystal Reports.

In the design view, I added my face to the Report Header and you can see some fields like [Report Title], [Author] and [Page Number]. these are Special Fields that will pull from the report properties. The text in the page header is hard coded and will appear on every page, as will the footer. The magic happens in the Details Section. I will drag fields from my Excel sheet to this section and it will populate the data for me.

You can see on the left, I have all the fields that are in the Excel sheet. I can drag them to the Details and the Header will automatically get the title. There is only one line in this report, but it will duplicate the data values for each record in the schedule.

Crystal reports is very powerful. You can group and sort, filter, and add subtotals, running totals, and grand totals. You can also add formulas that operate on fields.

Here is the finished report.

Here is the PDF: REPORT.PDF  

You can export to many different formats. By saving out any schedules from different projects to the same Excel file, you can run the report on new data just by opening it. (Overwrite WallSchedule.XLS with every new Revit wall schedule. ) The data connection remains and the fields all have the same names.
This post was a bit rushed, but I hope the point is clear: Crystal Reports can create Revit reports that are far more attractive and powerful than Revit can — at the moment. My report is not beautiful, but Google some samples and you will see their power.

This report shows a little more: Better Report.PDF