Circuit Outage Map--Search For a Substation Name or Circuit Number

You can enter a search term in the input box below and then select the feeder from the list that appears below the input box.



# load interruption & map data
source(RpadBaseFile('imagemap.R'))
source(RpadBaseFile('html_extra_utils.R'))
load(RpadBaseFile('utility_gis.RData')) # cir, circuits.df, circuits.seg, ints, subs, swtchs

cat('sublist = Array') 
cat(sub("^c","",capture.output(dput(as.character(cir$id)))))
cat(';handleKeyUp(20);document.getElementById("subinput").focus();')
chosencircuit = cir$circuit[cir$id == subselect]
im = imagemap("Plot", width = 750, height = 600) 
idx = circuits.df$circuit[circuits.seg$idx] %in% chosencircuit
seg = circuits.seg[idx,]
par(mar=c(2,.5,0,9.5))
plot.new()
plot.window(xlim=range(seg$x1, seg$x2),
            ylim=range(seg$y1, seg$y2),
            asp=1, yaxs = "i")

# CIRCUITS 
library(RColorBrewer)
palette(brewer.pal(12,"Set2"))
desc = circuits.df$Descrptn[circuits.seg$idx][idx]
lwd = array(.5,length(idx))
lwd[grep("Feeder|Cable",as.character(desc))] = 2
segments(seg$x1, seg$y1, seg$x2, seg$y2,
         col = as.numeric(desc), lwd = lwd)

# CIRCUIT LEGEND  
par(xpd = TRUE) # allow drawing outside the boundary
legidx = levels(desc) %in% levels(desc[,drop=T])
lwd = array(.8,length(levels(circuits.df$Descrptn)))
lwd[grep("Feeder|Cable",levels(circuits.df$Descrptn))] = 2.5
legend(x = approx(y=par()$usr[1:2], x=0:1, xout=.999)$y,
       y = approx(y=par()$usr[3:4], x=0:1, xout=.05)$y,
       levels(circuits.df$Descrptn)[legidx], 
       col = (1:19)[legidx], 
       lty = 1,
       lwd = lwd[legidx], 
       bty = "n", cex = .9, yjust = 0)
par(xpd = FALSE) # restore clipping

# SUBSTATIONS  
points(subs[,c("x","y")], pch = 4, cex = 3,col="blue")

# SWITCHES  
swtchsidx = swtchs$Fac_cd %in% chosencircuit & !(swtchs$Feature %in% "Fuse")
points(swtchs[swtchsidx,c("x","y")], 
       pch = 18,
       col=as.numeric(swtchs$Feature[swtchsidx]), cex=.8)

# FAULTS  
palette(c("black", "gray", "blue", "yellow", "green3"))
# cause order is: "O" "E" "A" "L" "T"
circuitints = ints[ints$fltcircuit %in% chosencircuit,]
# sort to get the largest interruptions on top
circuitints = circuitints[order(circuitints$restmeters),] 
ints.subset = circuitints[, c('intdate','restmeters','duratnminutes', 
                              'cause','weather','isodevdecsr')]

points(circuitints[, c("x","y")], pch = 1, cex = 1.5,
       col = as.numeric(circuitints$cause1),
       lwd = ifelse(circuitints$restmeters > 200, 4, .5)
)

# FAULT LEGEND  
par(xpd = TRUE) # allow drawing outside the boundary
legend(x = approx(y=par()$usr[1:2], x=0:1, xout=.999)$y,
       y = approx(y=par()$usr[3:4], x=0:1, xout=.95)$y,
       levels(circuitints$cause1), 
       col = 1:5, 
       pch = 1, 
       pt.lwd = 2, 
       bty = "n")
par(xpd = FALSE) # restore clipping

# CIRCUIT LABEL  
mtext(subselect, side = 1, adj = 1, padj = 1)


# MAP SCALE  
mapscale = axTicks(1)[1:3]
axis(1, 
     at = pretty(mapscale)[1:3], 
     lab = paste((mapscale - mapscale[1]) / 1000, c("", "", " kft"),sep=""))


# IMAGEMAP  
# make the image map boundaries
for (i in rev(seq(along=circuitints$x)))
  addRegion(im) <- imPoint( circuitints[i,]$x, circuitints[i,]$y, 600, 400,
    onmouseover = 
      paste("javascript:document.getElementById('results').innerHTML =", 
            " data[", i-1, "]", sep="")
    ) 

dummy = capture.output(imClose(im)) # the capture.output is just to hide the output

HTMLon()
# Now, we can make the HTML for display:

HTMLtag("span", contenteditable="false")

# create a javascript data array and stuff it with HTML results for
# use in the browser
# it doesn't need to go back to the server for this
js = file("data.js", "wt")
cat(file=js, 'data = Array(') 
cat(file=js, HTML.individual.row.of.df(ints.subset, class="Rpad"))  
     #  HTML.individual.row.of.df defined in html_extra_utils.R
cat(file=js, "' ');\n;")
close(js)
#runjavascript(RpadURL('data.js')) # now done below

# display the image with the imagemap
#HTMLh4(subselect)
HTMLtag('div', style="height:600px; width:800px") # fixed-height wrapper prevents jumpiness
createIM(im) 
HTMLetag('div')
HTMLtag("style")
cat('table.Rpad {text-align: center;  padding: 10px; width:700px;}')
HTMLetag("style")
  
# Create a DIV to display the interactive updates.
# The result is absolutely positioned relative to the graphic.
# Use top & left to adjust the position.
HTMLtag("span", id="results")
HTMLh3("&nbsp;")
HTMLetag("span")
HTMLetag("span")
  
# hacky way to write and run some javascript to fill in the data shown when mousing over:
cat('(e=document.createElement("script")).src="',
    RpadURL('data.js'),
#    '";e.type="text/javascript"; document.getElementsByTagName("head")[0].appendChild(e);e.parentNode.removeChild(e);', # deleting the element breaks IE
    '";e.type="text/javascript"; document.getElementsByTagName("head")[0].appendChild(e);',
    sep="")

Background

R has good support for GIS data. This example plots circuit data along with interruption locations in the past ten years (after selecting the circuit below). Outages are colored by cause code, and larger interruptions are plotted with a thicker symbol. If you move the mouse arrow over an interruption, more details in that outage are provided below the map. The GIS data was imported from ESRI shapefiles using the maptools package. The GIS data was then merged with the reliability database to obtain geographic coordinates for outages. This type of historical view could help utilities analyze worst circuits, target maintenance, and look for coordination problems.




by Tom Short, tshort@epri.com, Copyright 2005 EPRI